this is a followup on 'LPCTSTR typecast for use with GetFileAttributes'
i extended my method by GetLastError();.
I cast DWORD into a unsigned int and try to display it with a MessageBox.
the code does work, but i fail to visualize the value of DWORD dw or Unsigned int test from the GetLastError(); method using a MessageBox and figuring how to proceed.
this a win32 project and i trying to build a method to see if a file exist on the harddrive.
there are over 15.000 error codes and it´s imposible to hardcode them all.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx
BOOL FileExists(LPCTSTR szPath)
{
//MessageBox(NULL,szPath,L"File Error",MB_OK);
DWORD dwAttrib = GetFileAttributes(szPath);
unsigned int test;
DWORD dw = GetLastError();
test =(unsigned int)dw;
if(test == 0){
MessageBox(NULL,(LPCWSTR)test, L"Target == 0",MB_OK);
}
else
{
MessageBox(NULL,(LPCWSTR)test, L"Target != 0",MB_OK);
}
switch(dw)
{
case ERROR_SUCCESS:
MessageBox(NULL,L"ERROR_SUCCESS", L"File Error",MB_OK);
break;
case ERROR_PATH_NOT_FOUND:
MessageBox(NULL,L"ERROR_PATH_NOT_FOUND", L"File Error",MB_OK);
break;
default:
MessageBox(NULL,(LPCWSTR)dw, L"File Error",MB_OK);
break;
}
switch(dwAttrib)
{
case FILE_ATTRIBUTE_DIRECTORY:
MessageBox(NULL,L"FILE_ATTRIBUTE_DIRECTORY", L"File Error",MB_OK);
break;
case FILE_ATTRIBUTE_ARCHIVE:
MessageBox(NULL,L"FILE_ATTRIBUTE_ARCHIVE", L"File Error",MB_OK);
break;
case FILE_READ_ONLY_VOLUME:
MessageBox(NULL,L"FILE_READ_ONLY_VOLUME", L"File Error",MB_OK);
break;
case FILE_INVALID_FILE_ID:
MessageBox(NULL,L"FILE_INVALID_FILE_ID", L"File Error",MB_OK);
break;
//case INVALID_FILE_ATTRIBUTES:
// MessageBox(NULL,L"INVALID_FILE_ATTRIBUTES",L"File Error",MB_OK);
// break;
//case FILE_INVALID_FILE_ID:
// MessageBox(NULL,L"Failed to get image file,\\please check game folder",L"File Error",MB_OK);
// break;
default:
MessageBox(NULL,(LPCWSTR)dwAttrib,L"File Error",MB_OK);
break;
}
return true; // testing phase
}
The fundamental problem you have is that your casts are incorrect. When the compiler tells you that the parameters you pass have the wrong type, the correct approach is to find a way to pass something with the right type. Instead you cast the value which simply says to the compiler, "I know better than you, please ignore the type of the variable and pretend it is what I said it is."
So, instead of writing
(LPCWSTR)test
you need to convert the integer test to a null-terminated wide string. There are lots of ways to do that. For instance, you might use a string stream:
std::wstringstream sstream;
sstream << test;
std::wstring str = test.str();
Then you can pass str.c_str() to the MessageBox API.
In C++11 you could use std::to_wstring() like this:
std::wstring str = std::to_wstring();
You are interpreting the values returned by GetFileAttributes incorrectly. These are combinations of bit flags. In other words, multiple file attribute flags may be set. You need to use the bitwise and operator, & to test for the presence of the flags.
You also get the error checking badly wrong. The documentation says:
If the function fails, the return value is INVALID_FILE_ATTRIBUTES. To get extended error information, call GetLastError.
In other words, you should only call GetLastError when GetFileAttributes returns a value of INVALID_FILE_ATTRIBUTES. This is an incredibly common mistake, that of thinking that errors are indicated by GetLastError returning a non-zero value. You must read the documentation for each and every API function to be clear on how it signals errors.
Finally, if you do successfully obtain a valid Win32 error code, use FormatMessage to get a textual description of the error.
You cannot type-cast a DWORD into a string. You have to format it.
Your error checking is wrong.
On success, GetFileAttributes() can (and frequently does) return multiple attributes at a time, but you are not handling that possibility. And some of the values you are checking for are not even value attributes to begin with.
Try this instead:
BOOL FileExists(LPCTSTR szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
if (dwAttrib == INVALID_FILE_ATTRIBUTES)
{
DWORD dw = GetLastError();
switch (dw)
{
case ERROR_PATH_NOT_FOUND:
MessageBoxW(NULL, L"ERROR_PATH_NOT_FOUND", L"File Error", MB_OK);
break;
case ERROR_FILE_NOT_FOUND:
MessageBoxW(NULL, L"ERROR_FILE_NOT_FOUND", L"File Error", MB_OK);
break;
default:
{
std::wstringstream msg;
msg << L"Error Code: " << dw;
LPWSTR lpMsg = NULL;
if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dw, 0, (LPWSTR)&lpMsg, 0, NULL))
{
msg << std::endl << lpMsg;
LocalFree(lpMsg);
}
MessageBoxW(NULL, msg.str().c_str(), L"File Error", MB_OK);
break;
}
}
return false;
}
else
{
std::wstringstream attribs;
if (dwAttrib & FILE_ATTRIBUTE_READONLY)
{
attribs << L"FILE_ATTRIBUTE_READONLY" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_READONLY;
}
if (dwAttrib & FILE_ATTRIBUTE_HIDDEN)
{
attribs << L"FILE_ATTRIBUTE_HIDDEN" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_HIDDEN;
}
if (dwAttrib & FILE_ATTRIBUTE_SYSTEM)
{
attribs << L"FILE_ATTRIBUTE_SYSTEM" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_SYSTEM;
}
if (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)
{
attribs << L"FILE_ATTRIBUTE_DIRECTORY" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_DIRECTORY;
}
if (dwAttrib & FILE_ATTRIBUTE_ARCHIVE)
{
attribs << L"FILE_ATTRIBUTE_ARCHIVE" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_ARCHIVE;
}
if (dwAttrib & FILE_ATTRIBUTE_DEVICE)
{
attribs << L"FILE_ATTRIBUTE_DEVICE" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_DEVICE;
}
if (dwAttrib & FILE_ATTRIBUTE_NORMAL)
{
attribs << L"FILE_ATTRIBUTE_NORMAL" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_NORMAL;
}
if (dwAttrib & FILE_ATTRIBUTE_TEMPORARY)
{
attribs << L"FILE_ATTRIBUTE_TEMPORARY" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_TEMPORARY;
}
if (dwAttrib & FILE_ATTRIBUTE_SPARSE_FILE)
{
attribs << L"FILE_ATTRIBUTE_SPARSE_FILE" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_SPARSE_FILE;
}
if (dwAttrib & FILE_ATTRIBUTE_REPARSE_POINT)
{
attribs << L"FILE_ATTRIBUTE_REPARSE_POINT" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_REPARSE_POINT;
}
if (dwAttrib & FILE_ATTRIBUTE_COMPRESSED)
{
attribs << L"FILE_ATTRIBUTE_COMPRESSED" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_COMPRESSED;
}
if (dwAttrib & FILE_ATTRIBUTE_OFFLINE)
{
attribs << L"FILE_ATTRIBUTE_OFFLINE" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_OFFLINE;
}
if (dwAttrib & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)
{
attribs << L"FILE_ATTRIBUTE_NOT_CONTENT_INDEXED" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
}
if (dwAttrib & FILE_ATTRIBUTE_ENCRYPTED)
{
attribs << L"FILE_ATTRIBUTE_ENCRYPTED" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_ENCRYPTED;
}
if (dwAttrib & FILE_ATTRIBUTE_VIRTUAL)
{
attribs << L"FILE_ATTRIBUTE_VIRTUAL" << std::endl;
dwAttrib &= ~FILE_ATTRIBUTE_VIRTUAL;
}
if (dwAttrib != 0)
attribs << L"Other: " << std::hex << std::showbase << std::setw(8) << std::setfill(L'0') << dwAttribs << std::endl;
MessageBoxW(NULL, attribs.str().c_str(), L"File Attributes", MB_OK);
return true;
}
Related
I have written code to find installed modems on a computer. This can find the name of the device, which is useful for display purposes, but it can't yet find the COM port of the modem. I need this to use the device. How can I get this information, given what I can discover using the Microsoft Device and Drive installation API?
Here is the code:
/*
use CM_Get_Device_Interface_ListW and CM_Get_Device_Interface_List_SizeW for get
list of interfaces for GUID_DEVINTERFACE_COMPORT. query CM_Get_Device_Interface_PropertyW
with DEVPKEY_Device_InstanceId for get device id, than CM_Locate_DevNodeW and finally
you can query devnode for many properties - like DEVPKEY_NAME, etc.
*/
#include <Windows.h>
#include <cfgmgr32.h> // Device and Driver Installation header
#include <initguid.h> // Put this in to get rid of linker errors - unresolved external symbol _DEVPKEY_Device_DeviceDesc
#include <devpkey.h> // Property keys defined here are now defined inline. DEVPKEY_Device_DeviceDesc
// Microsoft Device and Driver Installation library
#pragma comment(lib, "Cfgmgr32.lib")
#include <Ntddmodm.h>
#include <iostream>
#include <string>
using namespace std;
const char* error2string(int err) {
switch (err) {
case CR_SUCCESS: return "CR_OK";
case CR_DEFAULT: return "CR_DEFAULT";
case CR_OUT_OF_MEMORY: return "CR_OUT_OF_MEMORY";
case CR_INVALID_POINTER: return "CR_INVALID_POINTER";
case CR_INVALID_FLAG: return "CR_INVALID_FLAG";
case CR_INVALID_DEVNODE: return "CR_INVALID_DEVNODE";
case CR_INVALID_RES_DES: return "CR_INVALID_RES_DES";
case CR_INVALID_LOG_CONF: return "CR_INVALID_LOG_CONF";
case CR_INVALID_ARBITRATOR: return "CR_INVALID_ARBITRATOR";
case CR_INVALID_NODELIST: return "CR_INVALID_NODELIST";
case CR_DEVNODE_HAS_REQS: return "CR_DEVNODE_HAS_REQS";
case CR_INVALID_RESOURCEID: return "CR_INVALID_RESOURCEID";
case CR_DLVXD_NOT_FOUND: return "CR_DLVXD_NOT_FOUND";
case CR_NO_SUCH_DEVNODE: return "CR_NO_SUCH_DEVNODE";
case CR_NO_MORE_LOG_CONF: return "CR_NO_MORE_LOG_CONF";
case CR_NO_MORE_RES_DES: return "CR_NO_MORE_RES_DES";
case CR_ALREADY_SUCH_DEVNODE: return "CR_ALREADY_SUCH_DEVNODE";
case CR_INVALID_RANGE_LIST: return "CR_INVALID_RANGE_LIST";
case CR_INVALID_RANGE: return "CR_INVALID_RANGE";
case CR_FAILURE: return "CR_FAILURE";
case CR_NO_SUCH_LOGICAL_DEV: return "CR_NO_SUCH_LOGICAL_DEV";
case CR_CREATE_BLOCKED: return "CR_CREATE_BLOCKED";
case CR_NOT_SYSTEM_VM: return "CR_NOT_SYSTEM_VM";
case CR_REMOVE_VETOED: return "CR_REMOVE_VETOED";
case CR_APM_VETOED: return "CR_APM_VETOED";
case CR_INVALID_LOAD_TYPE: return "CR_INVALID_LOAD_TYPE";
case CR_BUFFER_SMALL: return "CR_BUFFER_SMALL";
case CR_NO_ARBITRATOR: return "CR_NO_ARBITRATOR";
case CR_NO_REGISTRY_HANDLE: return "CR_NO_REGISTRY_HANDLE";
case CR_REGISTRY_ERROR: return "CR_REGISTRY_ERROR";
case CR_INVALID_DEVICE_ID: return "CR_INVALID_DEVICE_ID";
case CR_INVALID_DATA: return "CR_INVALID_DATA";
case CR_INVALID_API: return "CR_INVALID_API";
case CR_DEVLOADER_NOT_READY: return "CR_DEVLOADER_NOT_READY";
case CR_NEED_RESTART: return "CR_NEED_RESTART";
case CR_NO_MORE_HW_PROFILES: return "CR_NO_MORE_HW_PROFILES";
case CR_DEVICE_NOT_THERE: return "CR_DEVICE_NOT_THERE";
case CR_NO_SUCH_VALUE: return "CR_NO_SUCH_VALUE";
case CR_WRONG_TYPE: return "CR_WRONG_TYPE";
case CR_INVALID_PRIORITY: return "CR_INVALID_PRIORITY";
case CR_NOT_DISABLEABLE: return "CR_NOT_DISABLEABLE";
case CR_FREE_RESOURCES: return "CR_FREE_RESOURCES";
case CR_QUERY_VETOED: return "CR_QUERY_VETOED";
case CR_CANT_SHARE_IRQ: return "CR_CANT_SHARE_IRQ";
case CR_NO_DEPENDENT: return "CR_NO_DEPENDENT";
case CR_SAME_RESOURCES: return "CR_SAME_RESOURCES";
case CR_NO_SUCH_REGISTRY_KEY: return "CR_NO_SUCH_REGISTRY_KEY";
case CR_INVALID_MACHINENAME: return "CR_INVALID_MACHINENAME";
case CR_REMOTE_COMM_FAILURE: return "CR_REMOTE_COMM_FAILURE";
case CR_MACHINE_UNAVAILABLE: return "CR_MACHINE_UNAVAILABLE";
case CR_NO_CM_SERVICES: return "CR_NO_CM_SERVICES";
case CR_ACCESS_DENIED: return "CR_ACCESS_DENIED";
case CR_CALL_NOT_IMPLEMENTED: return "CR_CALL_NOT_IMPLEMENTED";
case CR_INVALID_PROPERTY: return "CR_INVALID_PROPERTY";
case CR_DEVICE_INTERFACE_ACTIVE: return "CR_DEVICE_INTERFACE_ACTIVE";
case CR_NO_SUCH_DEVICE_INTERFACE: return "CR_NO_SUCH_DEVICE_INTERFACE";
case CR_INVALID_REFERENCE_STRING: return "CR_INVALID_REFERENCE_STRING";
case CR_INVALID_CONFLICT_LIST: return "CR_INVALID_CONFLICT_LIST";
case CR_INVALID_INDEX: return "CR_INVALID_INDEX";
case CR_INVALID_STRUCTURE_SIZE: return "CR_INVALID_STRUCTURE_SIZE";
case NUM_CR_RESULTS: return "NUM_CR_RESULTS";
default: return "unknown";
}
}
void printerror(int line, int code) {
cout << "error: " << error2string(code) << " on line " << line << endl;
}
void print_filtered_devices() {
/* find properties for GUID_DEVINTERFACE_COMPORT and GUID_DEVINTERFACE_MODEM */
LPGUID InterfaceClassGuid = (LPGUID)&GUID_DEVINTERFACE_MODEM;
PWSTR DeviceList = NULL;
ULONG DeviceListLength = 0;
CONFIGRET cr = CM_Get_Device_Interface_List_SizeW(&DeviceListLength, InterfaceClassGuid, 0, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cr == CR_SUCCESS) {
DeviceList = (PWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DeviceListLength * sizeof(WCHAR));
cr = CM_Get_Device_Interface_ListW(InterfaceClassGuid, NULL, DeviceList, DeviceListLength, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cr == CR_SUCCESS) {
for (PWSTR CurrentDevice = DeviceList; *CurrentDevice; CurrentDevice += wcslen(CurrentDevice) + 1) {
wcout << L"interface = " << CurrentDevice << endl;
DEVPROPTYPE PropertyType;
WCHAR buf[1024];
ULONG BufferSize = sizeof(buf);
cr = CM_Get_Device_Interface_PropertyW(CurrentDevice, &DEVPKEY_Device_InstanceId, &PropertyType, (PBYTE)buf, &BufferSize, 0);
cout << "CM_Get_Device_Interface_PropertyW returned: " << error2string(cr) << endl;
DEVINST Devinst;
cr = CM_Locate_DevNodeW(&Devinst, buf, CM_LOCATE_DEVNODE_NORMAL);
cout << "CM_Locate_DevNodeW returned: " << error2string(cr) << endl;
if (cr == CR_SUCCESS) {
// Query a property on the device. For example, the device description.
WCHAR DeviceDesc[2048];
ULONG PropertySize = sizeof(DeviceDesc);
cr = CM_Get_DevNode_PropertyW(Devinst,
&DEVPKEY_Device_DeviceDesc,
&PropertyType,
(PBYTE)DeviceDesc,
&PropertySize,
0);
cout << "CM_Get_DevNode_PropertyW returned: " << error2string(cr) << endl;
if (cr == CR_SUCCESS && PropertyType == DEVPROP_TYPE_STRING) {
// print device
wcout << "DEVPKEY_Device_DeviceDesc=" << DeviceDesc << endl;
wcout << "";
}
else {
printerror(__LINE__, cr);
}
//WCHAR DeviceDesc[2048];
PropertySize = sizeof(DeviceDesc);
cr = CM_Get_DevNode_PropertyW(Devinst,
&DEVPKEY_NAME,
&PropertyType,
(PBYTE)DeviceDesc,
&PropertySize,
0);
cout << "CM_Get_DevNode_PropertyW returned: " << error2string(cr) << endl;
if (cr == CR_SUCCESS && PropertyType == DEVPROP_TYPE_STRING) {
// print device
wcout << "DEVPKEY_NAME=" << DeviceDesc << endl;
wcout << "";
}
else {
printerror(__LINE__, cr);
}
//Need a port property???
}
else {
printerror(__LINE__, cr);
}
}
}
else {
printerror(__LINE__, cr);
}
}
else {
printerror(__LINE__, cr);
}
if (DeviceList != NULL) {
HeapFree(GetProcessHeap(), 0, DeviceList);
}
}
int main() {
// This call fails to retrieve any devices of class GUID_DEVINTERFACE_COMPORT
print_filtered_devices();
}
And on my PC I get this output:
interface = \\?\USB#VID_0572&PID_1340#12345678#{2c7089aa-2e0e-11d1-b114-00c04fc2aae4}
CM_Get_Device_Interface_PropertyW returned: CR_OK
CM_Locate_DevNodeW returned: CR_OK
CM_Get_DevNode_PropertyW returned: CR_OK
DEVPKEY_Device_DeviceDesc=Conexant USB CX93010 ACF Modem
CM_Get_DevNode_PropertyW returned: CR_OK
DEVPKEY_NAME=Conexant USB CX93010 ACF Modem
This is the first time calling Sleep_Detection() which is a function that includes RegisterClass():
//some codes here...
Execute_Command(0);
Sleep_Detection(); **//First time calling, no problem**
This is the second time calling Sleep_Detection() but it's now calling from inside of the SleepDetectionProc() callback function, the error occurred here.
I used GetLastError() and here I got an error code of 1410 which means "ERROR_CLASS_ALREADY_EXISTS".
LRESULT _stdcall SleepDetectionProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_POWERBROADCAST)
{
if (wParam == PBT_APMRESUMESUSPEND)
{
cout << "System restored" << endl;
Execute_Command(0);
Sleep_Detection(); **//Second time calling, error code 1410**
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
This is the Sleep_Detection() function:
void Sleep_Detection(void)
{
WNDCLASS WindowClass = { 0 };
WindowClass.lpfnWndProc = SleepDetectionProc;
WindowClass.lpszClassName = (L"Sleep detection");
if (!GetClassInfo(WindowClass.hInstance, WindowClass.lpszClassName, &WindowClass))
{
if (!RegisterClass(&WindowClass))
{
cout << "Cannot register class (Error Code: " << GetLastError() << ")" << endl;
exit(EXIT_FAILURE);
}
else
cout << "registered" << endl;
}
else
cout << "Class already exists" << endl;
HWND WinHandle = NULL;
if (!FindWindow(WindowClass.lpszClassName, ConsoleTitle))
{
if ((WinHandle = CreateWindow(L"Sleep detection", L"", 0, 0, 0, 0, 0, NULL, NULL, NULL, 0)) == NULL)
{
cout << "Cannot create window (Error Code: " << GetLastError() << ")" << endl;
exit(EXIT_FAILURE);
}
else
cout << "window created" << endl;
}
else
cout << "Window already exists" << endl;
int upRes;
MSG Message;
while (upRes = GetMessage(&Message, WinHandle, 0, 0))
{
if (upRes == -1)
{
cout << "An error occurred when getting window messages (Error Code: " << GetLastError() << endl;
exit(EXIT_FAILURE);
}
else
{
cout << "Got Message!" << endl;
TranslateMessage(&Message);
DispatchMessage(&Message);
}
}
}
So I basically called Sleep_Detection() twice and it also called the RegisterClass() function inside. I guess the error could be related to overwritten the RegisterClass()?
WNDCLASS WindowClass = { 0 };
WindowClass.lpfnWndProc = SleepDetectionProc;
WindowClass.lpszClassName = (L"Sleep detection");
WindowClass.hInstance is zero, which will cause GetClassInfo() to fail even if the window class already exists, because the value of NULL for the parameter hInstance is reserved for classes defined by the system, which is stated at the MSDN page:
hInstance
A handle to the instance of the application that created the class. To
retrieve information about classes defined by the system (such as
buttons or list boxes), set this parameter to NULL.
So RegisterClass will always be attempted, which of course fails on the 2nd try.
To correct the error, initialize WindowClass.hInstance like this:
WindowClass.hInstance = GetModuleHandle(NULL); // get hInstance of current process
If the code is called from a DLL, replace GetModuleHandle(NULL) with the handle of that DLL. By the way, HMODULE is interchangeable with HINSTANCE, that is the base address of the module.
I have a client using libwebsocket to establish a connection to a server. Whenever the client sends a request, the server sends a response and after receiving the response the client closes the connection. Works fine.
But when the server does not answer to the request i have the problem that the client keeps waiting for a response forever. When nothing happens the callback is never called and its not possible to close connection with returning -1 from callback function.
Is there any way to enable a timeout for the connection to close? Or any possibility to close connection from outside the callback function?
Here is my code so far:
int callback_function(libwebsocket_context* context, libwebsocket* wsi, enum libwebsocket_callback_reasons reason, void* user, void* in, size_t len) {
switch (reason) {
case LWS_CALLBACK_CLIENT_ESTABLISHED: {
std::cout << "LWS_CALLBACK_CLIENT_ESTABLISHED" << std::endl;
libwebsocket_callback_on_writable(context, wsi);
}
break;
case LWS_CALLBACK_CLOSED:{
std::cout << "LWS_CALLBACK_CLOSED" << std::endl;
}
break;
case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
case LWS_CALLBACK_CLIENT_RECEIVE:{
std::cout << "LWS_CALLBACK_CLIENT_RECEIVE" << endl;
((char *)in)[len] = '\0';
answers_[current_request] = answers_[current_request] + string((char *)in);
if (libwebsocket_is_final_fragment(wsi)){
std::cout << "request:" << requests_[current_request] << std::endl;
std::cout << "answer:" << answers_[current_request] << std::endl;
current_request++;
if(current_request >= answers_.size()) {
ready = true;
return -1;
}
libwebsocket_callback_on_writable(context, wsi);
}
}
break;
case LWS_CALLBACK_CLIENT_WRITEABLE:{
std::cout << "LWS_CALLBACK_CLIENT_WRITEABLE" << endl;
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 + LWS_SEND_BUFFER_POST_PADDING];
const std::string message = std::string(requests_[current_request]);
std::copy(message.begin(), message.end(), &buf[LWS_SEND_BUFFER_PRE_PADDING]);
buf[LWS_SEND_BUFFER_PRE_PADDING+(int)message.size()]='\0';
int n = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], (size_t)message.size(), static_cast<libwebsocket_write_protocol>(LWS_WRITE_BINARY));
if (n < 0){
std::cout << kLogErr << "bad things are happening" << std::endl;
return -1;
}
if (n < (int)message.size()) {
std::cout << kLogErr << "Partial write LWS_CALLBACK_CLIENT_WRITEABLE" << std::endl;
return -1;
}
}
break;
default:
std::cout << "CALLBACK_DEFAULT: " << reason << endl;
break;
}
return 0;
}
vector<string> sendMessage(const string& server, int port, const string& path, const vector<string>& messages, bool& error) {
ready = error = false;
current_request = 0;
requests_ = vector<string>(messages);
answers_ = vector<string>(requests_.size(), "");
int ietf_version = -1; /* latest */
wsi_ = libwebsocket_client_connect(context_, server.c_str(), port, 2, path.c_str(), server.c_str(), "origin", NULL, ietf_version);
if (wsi_ == NULL) {
std::cout << kLogErr << "libwebsocket connect failed server:" << server << " port: " << port << " path: " << path << std::endl;
error = true;
return vector<string>();
}
bool first_time = true;
int n = 0;
while (n >= 0 && !force_exit && !ready) {
n = libwebsocket_service(context_, 0);
if(first_time) {
libwebsocket_callback_on_writable(context_, wsi_);
first_time = false;
}
if (n < 0){
continue;
}
if (wsi_ == NULL) {
break;
}
}
error = !ready;
wsi_ = NULL;
return vector<string>(answers_);
}
You could try using:
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
return -1;
break;
Or
lws_set_timeout
But I'm not a 100% sure that will work, you could also try creating an issue/question on their GitHub, they tend to answer quite fast/clear.
I'm also not sure if you should implement
I solved the problem.
I programmed a timer in
vector<string> sendMessage(const string& server, int port, const string& path, const vector<string>& messages, bool& error)
and when the timeout is reaches, the timer sets a flag and triggers
libwebsocket_callback_on_writable(context_, wsi_);
again. Then in
int callback_function(libwebsocket_context* context, libwebsocket* wsi, enum libwebsocket_callback_reasons reason, void* user, void* in, size_t len)
in case
LWS_CALLBACK_CLIENT_WRITEABLE
i check the flag and if it is set the callback is aborted with
return -1;
Works fine!
I want to develop an application in vc++ using which i want to display all the usb storage devices details connected to my pc. please tell me whether any APIs available for this. Any help will greatly be appreciated. Thanks...
You can use the SetupAPI methods (try these functions SetupDiGetClassDevs, SetupDiEnumDeviceInfo, SetupDiGetDeviceProperty) or you can use the Win32_DiskDrive WMI class and check if the InterfaceType property value is USB.
Try this sample code which uses the WMI to enumerate all the USB drives.
#include "stdafx.h"
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib")
//CREDENTIAL structure
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788%28v=vs.85%29.aspx
#define CRED_MAX_USERNAME_LENGTH 513
#define CRED_MAX_CREDENTIAL_BLOB_SIZE 512
#define CREDUI_MAX_USERNAME_LENGTH CRED_MAX_USERNAME_LENGTH
#define CREDUI_MAX_PASSWORD_LENGTH (CRED_MAX_CREDENTIAL_BLOB_SIZE / 2)
#pragma argsused
int main(int argc, char* argv[])
{
wchar_t pszName[CREDUI_MAX_USERNAME_LENGTH+1] = L"user";
wchar_t pszPwd[CREDUI_MAX_PASSWORD_LENGTH+1] = L"password";
BSTR strNetworkResource;
//To use a WMI remote connection set localconn to false and configure the values of the pszName, pszPwd and the name of the remote machine in strNetworkResource
bool localconn = true;
strNetworkResource = localconn ? L"\\\\.\\root\\CIMV2" : L"\\\\remote--machine\\root\\CIMV2";
COAUTHIDENTITY *userAcct = NULL ;
COAUTHIDENTITY authIdent;
// Initialize COM. ------------------------------------------
HRESULT hres;
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Set general COM security levels --------------------------
if (localconn)
hres = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
else
hres = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IDENTIFY, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
if (FAILED(hres))
{
cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Obtain the initial locator to WMI -------------------------
IWbemLocator *pLoc = NULL;
hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hres))
{
cout << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices *pSvc = NULL;
if (localconn)
hres = pLoc->ConnectServer(
_bstr_t(strNetworkResource), // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags.
0, // Authority (e.g. Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
else
hres = pLoc->ConnectServer(
_bstr_t(strNetworkResource), // Object path of WMI namespace
_bstr_t(pszName), // User name
_bstr_t(pszPwd), // User password
NULL, // Locale
NULL, // Security flags
NULL, // Authority
NULL, // Context object
&pSvc // IWbemServices proxy
);
if (FAILED(hres))
{
cout << "Could not connect. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
cout << "Connected to root\\CIMV2 WMI namespace" << endl;
// Set security levels on the proxy -------------------------
if (localconn)
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
else
{
// Create COAUTHIDENTITY that can be used for setting security on proxy
memset(&authIdent, 0, sizeof(COAUTHIDENTITY));
authIdent.PasswordLength = wcslen (pszPwd);
authIdent.Password = (USHORT*)pszPwd;
authIdent.User = (USHORT*)pszName;
authIdent.UserLength = wcslen(pszName);
authIdent.Domain = 0;
authIdent.DomainLength = 0;
authIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
userAcct = &authIdent;
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_DEFAULT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_DEFAULT, // RPC_C_AUTHZ_xxx
COLE_DEFAULT_PRINCIPAL, // Server principal name
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
userAcct, // client identity
EOAC_NONE // proxy capabilities
);
}
if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Use the IWbemServices pointer to make requests of WMI ----
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery( L"WQL", L"SELECT * FROM Win32_DiskDrive Where InterfaceType='USB'",
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
if (FAILED(hres))
{
cout << "ExecQuery failed" << " Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Secure the enumerator proxy
if (!localconn)
{
hres = CoSetProxyBlanket(
pEnumerator, // Indicates the proxy to set
RPC_C_AUTHN_DEFAULT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_DEFAULT, // RPC_C_AUTHZ_xxx
COLE_DEFAULT_PRINCIPAL, // Server principal name
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
userAcct, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
cout << "Could not set proxy blanket on enumerator. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pEnumerator->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
}
// Get the data from the WQL sentence
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if(0 == uReturn || FAILED(hr))
break;
VARIANT vtProp;
hr = pclsObj->Get(L"Caption", 0, &vtProp, 0, 0);// String
if (!FAILED(hr))
{
if ((vtProp.vt==VT_NULL) || (vtProp.vt==VT_EMPTY))
wcout << "Caption : " << ((vtProp.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
else
wcout << "Caption : " << vtProp.bstrVal << endl;
}
VariantClear(&vtProp);
hr = pclsObj->Get(L"DeviceID", 0, &vtProp, 0, 0);// String
if (!FAILED(hr))
{
if ((vtProp.vt==VT_NULL) || (vtProp.vt==VT_EMPTY))
wcout << "DeviceID : " << ((vtProp.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
else
wcout << "DeviceID : " << vtProp.bstrVal << endl;
}
VariantClear(&vtProp);
hr = pclsObj->Get(L"Model", 0, &vtProp, 0, 0);// String
if (!FAILED(hr))
{
if ((vtProp.vt==VT_NULL) || (vtProp.vt==VT_EMPTY))
wcout << "Model : " << ((vtProp.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
else
wcout << "Model : " << vtProp.bstrVal << endl;
}
VariantClear(&vtProp);
hr = pclsObj->Get(L"PNPDeviceID", 0, &vtProp, 0, 0);// String
if (!FAILED(hr))
{
if ((vtProp.vt==VT_NULL) || (vtProp.vt==VT_EMPTY))
wcout << "PNPDeviceID : " << ((vtProp.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
else
wcout << "PNPDeviceID : " << vtProp.bstrVal << endl;
}
VariantClear(&vtProp);
pclsObj->Release();
pclsObj=NULL;
}
// Cleanup
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
if (pclsObj!=NULL)
pclsObj->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 0; // Program successfully completed.
}
I am trying to find out the job id's by passing command line argument using WMI.
int main(int argc, char **argv)
{
HRESULT hres;
// Initialize COM.
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
cout << "Failed to initialize COM library. "
<< "Error code = 0x"
<< hex << hres << endl;
return 1; // Program has failed.
}
// Initialize
hres = CoInitializeSecurity(
NULL,
-1, // COM negotiates service
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
if (FAILED(hres))
{
cout << "Failed to initialize security. "
<< "Error code = 0x"
<< hex << hres << endl;
CoUninitialize();
return 1; // Program has failed.
}
// Obtain the initial locator to Windows Management
// on a particular host computer.
IWbemLocator *pLoc = 0;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hres))
{
cout << "Failed to create IWbemLocator object. "
<< "Error code = 0x"
<< hex << hres << endl;
CoUninitialize();
return 1; // Program has failed.
}
IWbemServices *pSvc = 0;
// Connect to the root\cimv2 namespace with the
// current user and obtain pointer pSvc
// to make IWbemServices calls.
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), // WMI namespace
NULL, // User name
NULL, // User password
0, // Locale
NULL, // Security flags
0, // Authority
0, // Context object
&pSvc // IWbemServices proxy
);
if (FAILED(hres))
{
cout << "Could not connect. Error code = 0x"
<< hex << hres << endl;
pLoc->Release();
CoUninitialize();
return 1; // Program has failed.
}
cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;
// Set the IWbemServices proxy so that impersonation
// of the user (client) occurs.
hres = CoSetProxyBlanket(
pSvc, // the proxy to set
RPC_C_AUTHN_WINNT, // authentication service
RPC_C_AUTHZ_NONE, // authorization service
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // authentication level
RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 1; // Program has failed.
}
// Use the IWbemServices pointer to make requests of WMI.
// Make requests here:
// For example, query for all the running processes
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_Process where CommandLine like 'commandLineString'"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
cout << " After execquery"<< endl ;
if (FAILED(hres))
{
cout << "Query for processes failed. "
<< "Error code = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 1; // Program has failed.
}
else
{
IWbemClassObject *pclsObj;
ULONG uReturn = 0;
while (pEnumerator)
{
hres = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);
if(0 == uReturn)
{
break;
}
VARIANT vtProp;
// Get the value of the Name property
hres = pclsObj->Get(L"ProcessId", 0, &vtProp, 0, 0);
int processId = (int)vtProp.intVal;
cout << "Process ID : " << processId << endl;
DWORD dwProcessId = (DWORD) processId;
DWORD dwDesiredAccess = PROCESS_TERMINATE;
BOOL bInheritHandle = FALSE;
HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
if (hProcess == NULL)
{
cout << "hProcess is null " << endl;
}else {
BOOL result = TerminateProcess(hProcess, 1);
CloseHandle(hProcess);
cout << "Process is terminated " << result <<endl;
}
} // while
} // else
// Cleanup
// ========
pLoc->Release();
pSvc->Release();
CoUninitialize();
getchar();
return 0; // Program successfully completed.
}
Above is the C++ code and my question is how do I access structure in nsis.
like the below lines in above code
1. hres = pLoc->ConnectServer(
2. hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
3. hres = pclsObj->Get
Please help me on this...
Have you looked at the WmiInspector plugin? Alternatively use your existing C++ code to create a custom plugin.
To call the Windows API or a COM interface in NSIS you have to use the system plugin:
!include LogicLib.nsh
!define CLSCTX_INPROC_SERVER 0x1
!define CLSID_ApplicationAssociationRegistrationUI {1968106d-f3b5-44cf-890e-116fcb9ecef1}
!define IID_IApplicationAssociationRegistrationUI {1f76a169-f994-40ac-8fc8-0959e8874710} ;[Vista+]
section
;NSIS has called CoInitialize
System::Call 'OLE32::CoCreateInstance(g "${CLSID_ApplicationAssociationRegistrationUI}",i 0,i ${CLSCTX_INPROC_SERVER},g "${IID_IApplicationAssociationRegistrationUI}",*i.r1)i.r0' ;ptr is now in $1 and hr in $0
${If} $1 <> 0
System::Call '$1->3(w "Internet Explorer")i.r0' ;IApplicationAssociationRegistrationUI::LaunchAdvancedAssociationUI
System::Call '$1->2()' ;IUnknown::Release
${EndIf}
sectionend
You have to manually look up IIDs and the vtable offset for methods so using a lot of COM is not going to be fun...