BHO object won't load, probable registration trouble? - bho

I can't get Internet Explorer or Windows Explorer to load this BHO. Sure there's no COM objects that can be created, but Explorer can't know that until it loads the DLL and checks, but LoadLibrary isn't getting called.
The message box shows when I run regsvr32.
Windows Version = 8.1
Internet Epxlorer Version = 11
Enhance Protected Mode on or off doesn't seem to make a difference.
#include <windows.h>
#include <olectl.h>
#include <stddef.h>
#include <string.h>
#define wstrlen wcslen
HINSTANCE me;
DWORD WINAPI M4(void *junk)
{
MessageBox(NULL, "Loaded", "bho", 0);
}
BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpReserved)
{
wchar_t mainexe[1024];
if (fdwReason == DLL_PROCESS_ATTACH) {
me = hInstDll;
DisableThreadLibraryCalls(me);
/* GetModuleFileNameW(NULL, mainexe, 1024); */
/* len = wstrlen(mainexe); */
HANDLE th = CreateThread(NULL, 32768, M4, NULL, 0, NULL);
}
return TRUE;
}
STDAPI DllGetClassObject(REFIID rclsid,REFIID riid,LPVOID *ppv)
{
return CLASS_E_CLASSNOTAVAILABLE;
}
STDAPI DllCanUnloadNow()
{
return FALSE;
}
const char *CLSID_NAME = "CLSID\\{2D3E480A-0000-0000-0000-64756D796C6472}";
const char *CLSID_IPS32 = "CLSID\\{2D3E480A-0000-0000-0000-64756D796C6472}\\InProcServer32";
const char *BHO = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects\\{2D3E480A-0000-0000-0000-64756D796C6472}";
const wchar_t *name = L"Redacted BHO";
const char *apt = "Apartment";
STDAPI DllRegisterServer()
{
HKEY hk;
wchar_t dllpath[1024];
GetModuleFileNameW(me,dllpath,1024);
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, CLSID_NAME, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hk, NULL) != ERROR_SUCCESS)
return SELFREG_E_CLASS;
RegSetValueExW(hk, NULL, 0, REG_SZ, (const BYTE *)(name), (wstrlen(name) + 1) << 1);
RegCloseKey(hk);
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, CLSID_IPS32, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hk, NULL) != ERROR_SUCCESS)
return SELFREG_E_CLASS;
RegSetValueExW(hk, NULL, 0, REG_SZ, (const BYTE *)(dllpath), (wstrlen(dllpath) + 1) << 1);
RegSetValueEx(hk, "ThreadingModel", 0, REG_SZ, (const BYTE *)(apt), 10);
RegCloseKey(hk);
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, BHO, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hk, NULL) != ERROR_SUCCESS)
return SELFREG_E_CLASS;
RegCloseKey(hk);
return S_OK;
}
STDAPI DllUnregisterServer()
{
RegDeleteKey(HKEY_LOCAL_MACHINE, BHO);
RegDeleteKey(HKEY_CLASSES_ROOT, CLSID_IPS32);
RegDeleteKey(HKEY_CLASSES_ROOT, CLSID_NAME);
}

For IE11 in enhanced protected mode (EPM), the registry must be updated with:
HKEY_CLASSES_ROOT\CLSID\{your BHO CLSID}\Implemented
Categories\{59FB2056-D625-48D0-A944-1A85B5AB2640}

Related

Why timeout param doesn't work in GetAddrInfoExW()?

When I try to call:
timeval timeout{ 0, 999 };
::GetAddrInfoExW(L"my_name", L"", NS_DNS, nullptr, nullptr, &pResult, &timeout, nullptr, nullptr, nullptr);
I got 10022 "Invalid params".
However, if I replace "&timeout" with "nullptr", I got 0 (OK).
Why the timeout causes EINVAL error?
UNICODE macro is defined, my system is Windows 10.
if timeout not 0, the lpOverlapped must be also not 0. the code can be next
#include <ws2tcpip.h>
struct QUERY_CONTEXT : OVERLAPPED
{
PADDRINFOEX _pResult;
ULONG _dwThreadId = GetCurrentThreadId();
~QUERY_CONTEXT()
{
if (PADDRINFOEX pResult = _pResult)
{
FreeAddrInfoEx(_pResult);
}
}
static void CALLBACK QueryCompleteCallback(
_In_ ULONG dwError,
_In_ ULONG /*dwBytes*/,
_In_ OVERLAPPED* lpOverlapped
)
{
static_cast<QUERY_CONTEXT*>(lpOverlapped)->OnComplete(dwError);
}
void OnComplete(_In_ ULONG dwError)
{
DbgPrint("OnComplete(%u)\n");
if (PADDRINFOEX pResult = _pResult)
{
do
{
WCHAR buf[64];
ULONG len = _countof(buf);
if (!WSAAddressToStringW(pResult->ai_addr, (ULONG)pResult->ai_addrlen, 0, buf, &len))
{
DbgPrint("%S\n", buf);
}
} while (pResult = pResult->ai_next);
}
PostThreadMessageW(_dwThreadId, WM_QUIT, dwError, 0);
delete this;
}
ULONG Query(_In_ PCWSTR pName, _In_opt_ timeval *timeout)
{
ULONG dwError = GetAddrInfoExW(pName, 0, NS_DNS, 0, 0,
&_pResult, timeout, this, QueryCompleteCallback, 0);
//
// If GetAddrInfoExW() returns WSA_IO_PENDING, GetAddrInfoExW will invoke
// the completion routine. If GetAddrInfoExW returned anything else we must
// invoke the completion directly.
//
if (dwError != WSA_IO_PENDING)
{
QueryCompleteCallback(dwError, 0, this);
}
return dwError;
}
};
///////////////////////////////////////
WSADATA wd;
if (NOERROR == WSAStartup(WINSOCK_VERSION, &wd))
{
if (QUERY_CONTEXT* pqc = new QUERY_CONTEXT {})
{
timeval timeout{ 1 };
pqc->Query(L"stackoverflow.com", &timeout);
}
MessageBoxW(0, 0, 0, 0);
WSACleanup();
}
also for dns query more efficient direct use DnsQueryEx function (GetAddrInfoExW internally call DnsQueryEx, but before this - alot of another code executed)

Capture encrypted USB decryption event?

hi I am using a Kingston DT4000 G2 USB drive with password protected.
I could track disk plug in & out event under windows by calling RegisterDeviceNotification(),
and receive notification by WM_DEVICECHANGE;
While the problem is the media is not available till I input password.
Before decryption I could see the device and system will show "Please insert a disk into USB drive (E:)".
But I can't capture the event when data is decrypted and media is really available to me.
Is there a such event could be captured using win32?
You could use following sample with GetLockStatus method of the Win32_EncryptableVolume
#include <windows.h>
#include <dbt.h>
#include <string>
#include <initguid.h>
#include <IoEvent.h>
#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
using namespace std;
#pragma comment(lib, "wbemuuid.lib")
#pragma warning(disable : 4996)
// Function prototype
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
std::string DrivesFromMask(ULONG unitmask);
UINT32 GetLockStatus();
int main(int argc, char** argv)
{
MSG msg; // MSG structure to store messages
HWND hwndMain; // Main window handle
WNDCLASSEX wcx; // WINDOW class information
HDEVNOTIFY hDevnotify;
DWORD len;
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
// 53F56307-B6BF-11D0-94F2-00A0C91EFB8B
GUID FilterGUID = { 0x53F56307,0x0B6BF,0x11D0,{0x94,0xF2,0x00,0xA0,0xC9,0x1E,0xFB,0x8B} };
// Initialize the struct to zero
ZeroMemory(&wcx, sizeof(WNDCLASSEX));
wcx.cbSize = sizeof(WNDCLASSEX); // Window size. Must always be sizeof(WNDCLASSEX)
wcx.style = 0; // Class styles
wcx.lpfnWndProc = (WNDPROC)MainWndProc; // Pointer to the callback procedure
wcx.cbClsExtra = 0; // Extra byte to allocate following the wndclassex structure
wcx.cbWndExtra = 0; // Extra byte to allocate following an instance of the structure
wcx.hInstance = GetModuleHandle(NULL); // Instance of the application
wcx.hIcon = NULL; // Class Icon
wcx.hCursor = NULL; // Class Cursor
wcx.hbrBackground = NULL; // Background brush
wcx.lpszMenuName = NULL; // Menu resource
wcx.lpszClassName = "USB"; // Name of this class
wcx.hIconSm = NULL; // Small icon for this class
// Register this window class with MS-Windows
if (!RegisterClassEx(&wcx))
return 0;
// Create the window
hwndMain = CreateWindowEx(0,// Extended window style
"USB", // Window class name
"", // Window title
WS_POPUP, // Window style
0, 0, // (x,y) pos of the window
0, 0, // Width and height of the window
NULL, // HWND of the parent window (can be null also)
NULL, // Handle to menu
GetModuleHandle(NULL), // Handle to application instance
NULL); // Pointer to window creation data
// Check if window creation was successful
if (!hwndMain)
return 0;
// Make the window invisible
ShowWindow(hwndMain, SW_HIDE);
// Initialize device class structure
len = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
memset(&NotificationFilter, 0, len);
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = 5; // DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = FilterGUID;
// Register
hDevnotify = RegisterDeviceNotification(hwndMain, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
if (hDevnotify == NULL)
return 0;
// Process messages coming to this window
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// return value to the system
return msg.wParam;
}
HDEVNOTIFY RegisterDevice(HWND hWnd, PDEV_BROADCAST_DEVICEINTERFACE PdevDEVICEINTERFACE)
{
DEV_BROADCAST_HANDLE broadcast = { 0 };
broadcast.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
broadcast.dbch_devicetype = DBT_DEVTYP_HANDLE;
broadcast.dbch_handle = CreateFile(PdevDEVICEINTERFACE->dbcc_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
return RegisterDeviceNotification(hWnd, &broadcast, DEVICE_NOTIFY_WINDOW_HANDLE);
}
HDEVNOTIFY hDevNotify = NULL;
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PDEV_BROADCAST_VOLUME PdevVolume;
PDEV_BROADCAST_DEVICEINTERFACE PdevDEVICEINTERFACE;
std::string drvs;
static UINT32 g_LockedDrivesMask;
switch (msg)
{
case WM_DEVICECHANGE:
switch (wParam)
{
// A device or piece of media has been inserted and is now available
case DBT_CUSTOMEVENT:
{
DEV_BROADCAST_HDR* hdr = (DEV_BROADCAST_HDR*)lParam;
switch (hdr->dbch_devicetype)
{
case DBT_DEVTYP_HANDLE:
UINT32 LockedDrivesMask = GetLockStatus();
UINT32 result = LockedDrivesMask ^ g_LockedDrivesMask;
if (result)
{
for (int i = 0; i < 26 && result; ++i)
{
if (result & 0x1)
{
if (0 == (LockedDrivesMask & (0x1 << i)))
printf("%c: unlock!\n", i + 'A');
}
result = result >> 1;
}
}
g_LockedDrivesMask = LockedDrivesMask;
break;
}
}
break;
case DBT_DEVICEARRIVAL:
PdevDEVICEINTERFACE = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
switch (PdevDEVICEINTERFACE->dbcc_devicetype)
{
// Class of devices
case DBT_DEVTYP_DEVICEINTERFACE:
g_LockedDrivesMask = GetLockStatus();
hDevNotify = RegisterDevice(hwnd, PdevDEVICEINTERFACE);
break;
// Logical volume
case DBT_DEVTYP_VOLUME:
PdevVolume = (PDEV_BROADCAST_VOLUME)lParam;
drvs = DrivesFromMask(PdevVolume->dbcv_unitmask);
for (UINT i = 0; i < drvs.length(); i++)
printf("Drive %c:\\ connected\n", drvs[i]);
}
break;
case DBT_DEVICEREMOVEPENDING:
PdevDEVICEINTERFACE = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
UnregisterDeviceNotification(hDevNotify);
}
break;
default:
// Call the default window handler
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
std::string DrivesFromMask(ULONG unitmask)
{
char i;
std::string drv = "";
for (i = 0; i < 26 && unitmask; ++i)
{
if (unitmask & 0x1)
{
drv += i + 'A';
}
unitmask = unitmask >> 1;
}
return drv;
}
UINT32 GetLockStatus()
{
HRESULT hres;
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
hres = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL
);
IWbemLocator* pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*)&pLoc);
IWbemServices* pSvc = NULL;
hres = pLoc->ConnectServer(
_bstr_t(L"Root\\CIMV2\\Security\\MicrosoftVolumeEncryption"), // Object path of WMI namespace
NULL,
NULL,
0,
NULL,
0,
0,
&pSvc
);
hres = CoSetProxyBlanket(
pSvc,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE
);
IEnumWbemClassObject* pEnumerator = NULL;
wstring strQuery = L"SELECT * FROM Win32_EncryptableVolume";
hres = pSvc->ExecQuery(BSTR(L"WQL"), BSTR(strQuery.c_str()),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
IWbemClassObject* pclsObj = NULL;
IWbemClassObject* pOutParams = NULL;
ULONG uReturn = 0;
UINT32 mask = 0;
while (pEnumerator)
{
UINT32 bit = 0;
hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (0 == uReturn || FAILED(hres))
break;
IWbemClassObject* pClass = NULL;
hres = pSvc->GetObject(BSTR(L"Win32_EncryptableVolume"), 0, NULL, &pClass, NULL);
VARIANT val;
hres = pclsObj->Get(L"DriveLetter", 0, &val, 0, NULL);
bit = val.bstrVal[0] - 'A';
IWbemClassObject* pInParamsDefinition = NULL;
hres = pClass->GetMethod(L"GetLockStatus", 0, NULL, NULL);
VARIANT var;
pclsObj->Get(L"__PATH", 0, &var, NULL, NULL);
hres = pSvc->ExecMethod(var.bstrVal, _bstr_t(L"GetLockStatus"), 0,
NULL, NULL, &pOutParams, NULL);
VARIANT varReturnValue;
hres = pOutParams->Get(_bstr_t(L"LockStatus"), 0,
&varReturnValue, NULL, 0);
if (varReturnValue.iVal)
{
mask |= 0x1 << bit;
}
VariantClear(&val);
VariantClear(&var);
VariantClear(&varReturnValue);
pclsObj->Release();
pClass->Release();
pOutParams->Release();
pOutParams = NULL;
}
pEnumerator->Release();
pLoc->Release();
pSvc->Release();
CoUninitialize();
return mask;
}
But please note that due to the Security Considerations, this sample must be run as admin.
Or without administrator privileges, you could use the polling method in this example:
https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/e0585eca-31fa-4fe4-873d-d87934cbbf9d/thread-not-working-if-winmain-arg-is-2?forum=windowssdk

Creating new registry entries in vc++

I am trying to create new registry entries which copies the certain registry values from HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings. I am successfully able to create the new registry entries but the values and sub key are not copied.I am not able to figure out where I have done the mistake. Please help me out.below is my code:
#include<tchar.h>
#include<conio.h>
#include<Windows.h>
#include<Winreg.h>
#include<WinBase.h >
#include<TlHelp32.h>
#define MAX_PATH 1024
DWORD MigrateProxy;
DWORD ProxyEnable;
DWORD ProxyHTTP11;
LPWSTR AutoConfigURL=0;
LPWSTR ProxyServer=0;
LPWSTR ProxyOverride=0;
void CopyRegistryProxySettings(HKEY hKeyRoot, LPCWSTR Subkey, LPCWSTR ValueKey);
bool CreateNewRegistry(HKEY hKeyRoot);
void main()
{
bool bStatusFlag = false,bReadFlag=false,bWriteFlag=false;
LPCWSTR lpSubKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
LPCWSTR lpValueName = L"AutoConfigURL";
CopyRegistryProxySettings(HKEY_CURRENT_USER, lpSubKey,lpValueName);
bStatusFlag = CreateNewRegistry(HKEY_CURRENT_USER);
//bWriteFlag = RestoreOlderRegistry()
getch();
}
void CopyRegistryProxySettings(HKEY hKeyRoot, LPCWSTR Subkey, LPCWSTR ValueKey)
{
HKEY hKey = NULL;
wchar_t buffer[MAX_PATH];
DWORD dwBufLen;
DWORD dwValue = 0;
DWORD dwDataSize = sizeof(DWORD);
memset(buffer, 0, sizeof buffer);
dwBufLen = MAX_PATH;
if ( ERROR_SUCCESS == RegOpenKeyEx(hKeyRoot, Subkey, 0, KEY_ALL_ACCESS , &hKey))
{
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"AutoConfigURL",NULL,NULL,(BYTE*)buffer,&dwBufLen))
{
AutoConfigURL = buffer;
memset(buffer, 0, sizeof buffer);
}
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"ProxyServer",NULL,NULL,(BYTE*)buffer,&dwBufLen))
{
ProxyServer = buffer;
memset(buffer, 0, sizeof buffer);
}
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"ProxyOverride",NULL,NULL,(BYTE*)buffer,&dwBufLen))
{
ProxyOverride = buffer;
memset(buffer, 0, sizeof buffer);
}
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"MigrateProxy",NULL,NULL,(LPBYTE)&dwValue,&dwDataSize))
{
MigrateProxy = dwValue;
}
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"ProxyEnable",NULL,NULL,(LPBYTE)&dwValue,&dwDataSize))
{
ProxyEnable = dwValue;
}
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"ProxyHttp1.1",NULL,NULL,(LPBYTE)&dwValue,&dwDataSize))
{
ProxyHTTP11 = dwValue;
}
}
}
bool CreateNewRegistry(HKEY hKeyRoot)
{
HKEY hKey;
if (RegCreateKeyEx(HKEY_CURRENT_USER, L"Software\\NewSettings\\Internet Settings", NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)
{
RegSetValueEx(hKey, L"AutoConfigURL", NULL,REG_SZ,(BYTE*)AutoConfigURL, (DWORD)((lstrlen(AutoConfigURL)+1)*sizeof(TCHAR)));
RegSetValueEx(hKey, L"ProxyServer", NULL,REG_SZ,(BYTE*)ProxyServer, (DWORD)((lstrlen(ProxyServer)+1)*sizeof(TCHAR)));
RegSetValueEx(hKey, L"ProxyOverride", NULL,REG_SZ,(BYTE*)ProxyOverride, (DWORD)((lstrlen(ProxyOverride)+1)*sizeof(TCHAR)));
RegSetValueEx(hKey, L"MigrateProxy", NULL,REG_DWORD,(BYTE*)MigrateProxy, (DWORD)sizeof(MigrateProxy));
RegSetValueEx(hKey, L"ProxyEnable", NULL,REG_DWORD,(BYTE*)ProxyEnable, (DWORD)sizeof(ProxyEnable));
RegSetValueEx(hKey, L"ProxyHTTP1.1", NULL, REG_DWORD,(BYTE*)ProxyHTTP11, (DWORD)sizeof(ProxyHTTP11));
}
return 1;
}

Getting the version of Renesas USB 3.0 Host Controller driver on Windows

Older versions of the Renesas USB 3.0 Host Controller have issues that may cause problems. To alert my customers of such problems, I need to detect outdated versions. To do this, I want to retrieve the running driver version same as the Renesas USB 3.0 Host Controller Utility does.
With OSR IrpTracker, I've determined the IOCTL and structure. Here's sample code that opens each Renesas USB Host Controller's device interface and queries the version number.
#include <initguid.h>
#include <windows.h>
#include <setupapi.h>
#include <stdlib.h>
#include <winioctl.h>
#include <pshpack1.h>
DEFINE_GUID(GUID_DEVINTERFACE_NUSB3XHC, 0xac051b02L, 0x603b, 0x4b3c, 0xb1, 0x4b, 0x95, 0xc9, 0x26, 0x8d, 0xe0, 0x81);
struct NUSB3XHC_DRIVER_VERSION
{
UCHAR Major;
UCHAR Minor;
UCHAR Build;
UCHAR Revision;
UCHAR Unknown[2]; // no idea what this is -- {0, 0} on my machine
};
struct NUSB3XHC_FIRMWARE_VERSION
{
USHORT BcdVersion; // UI displays this as BCD
};
#define IOCTL_NUSB3XHC_GET_DRIVER_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_NUSB3XHC_GET_FIRMWARE_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED, FILE_ANY_ACCESS)
#include <poppack.h>
BOOL GetVersion(LPCTSTR DevicePath, NUSB3XHC_DRIVER_VERSION* DriverVersion, NUSB3XHC_FIRMWARE_VERSION* FirmwareVersion)
{
HANDLE hDevice = CreateFile(DevicePath, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDevice == NULL)
return FALSE;
BOOL success = FALSE;
DWORD returned;
if (DeviceIoControl(hDevice, IOCTL_NUSB3XHC_GET_DRIVER_VERSION, NULL, 0, DriverVersion, sizeof(NUSB3XHC_DRIVER_VERSION), &returned, NULL))
{
success = (returned == sizeof(NUSB3XHC_DRIVER_VERSION));
}
if (DeviceIoControl(hDevice, IOCTL_NUSB3XHC_GET_FIRMWARE_VERSION, NULL, 0, FirmwareVersion, sizeof(NUSB3XHC_FIRMWARE_VERSION), &returned, NULL))
{
success = success && (returned == sizeof(NUSB3XHC_FIRMWARE_VERSION));
}
CloseHandle(hDevice);
return success;
}
int _tmain(int argc, _TCHAR* argv[])
{
int crap = IOCTL_NUSB3XHC_GET_FIRMWARE_VERSION;
HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_NUSB3XHC, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
if (hDevInfo != INVALID_HANDLE_VALUE)
{
SP_DEVICE_INTERFACE_DATA devIfaceData;
devIfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
DWORD Index = 0;
do
{
if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_NUSB3XHC, Index, &devIfaceData))
break; // hopefully ERROR_NO_MORE_ITEMS
DWORD requiredSize;
SetupDiGetDeviceInterfaceDetail(hDevInfo, &devIfaceData, NULL, NULL, &requiredSize, NULL);
// returns with ERROR_INSUFFICIENT_BUFFER
PSP_DEVICE_INTERFACE_DETAIL_DATA devIfaceDetailData =
(PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(requiredSize);
devIfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &devIfaceData, devIfaceDetailData, requiredSize, NULL, NULL))
{
NUSB3XHC_DRIVER_VERSION driverVersion;
NUSB3XHC_FIRMWARE_VERSION firmwareVersion;
if (GetVersion(devIfaceDetailData->DevicePath, &driverVersion, &firmwareVersion))
{
_tprintf(_T("%s: driver version: %d.%d.%d.%d, firmware version: %x\n"), devIfaceDetailData->DevicePath,
driverVersion.Major,
driverVersion.Minor,
driverVersion.Build,
driverVersion.Revision,
firmwareVersion.BcdVersion);
}
else
{
_tprintf(_T("Failed getting version data from %s.\n"), devIfaceDetailData->DevicePath);
}
}
free(devIfaceDetailData);
++Index;
}
while(1);
}
return 0;
}

How to convert LPWSTR to LPBYTE

I found many informations how to convert LPBYTE to LPWSTR, but no info about reverse process. I have tried do it on my own and tested such methods:
// my_documents declaration:
WCHAR my_documents[MAX_PATH];
//1st
const int size = WideCharToMultiByte(CP_UTF8, 0, my_documents, -1, NULL, 0, 0, NULL);
char *path = (char *)malloc( size );
WideCharToMultiByte(CP_UTF8, 0, my_documents, -1, path, size, 0, NULL);
//2nd
size_t i;
char *pMBBuffer = (char *)malloc( MAX_PATH );
cstombs_s(&i, pMBBuffer, MAX_PATH, my_documents, MAX_PATH-1 );
But when I write them to registry they are unreadable. And this is how I write them to registry:
BOOL SetKeyData(HKEY hRootKey, WCHAR *subKey, DWORD dwType, WCHAR *value, LPBYTE data, DWORD cbData)
{
HKEY hKey;
if(RegCreateKeyW(hRootKey, subKey, &hKey) != ERROR_SUCCESS)
return FALSE;
LSTATUS status = RegSetValueExW(hKey, value, 0, dwType, data, cbData);
if(status != ERROR_SUCCESS)
{
RegCloseKey(hKey);
return FALSE;
}
RegCloseKey(hKey);
return TRUE;
}
SetKeyData(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", REG_SZ, L"My program", (LPBYTE)path, size)
There is no problem with conversion, but when I try to write this to registry I get some strange chars
When you are writing a string to the wide registry functions you should not convert but pass a normal WCHAR*, just cast to LPBYTE. Just remember to get the size correct. LPBYTE is really for when you write a binary blob, every other type has to be casted...

Resources