📄 advprop.c
字号:
}
break;
}
case WM_INITDIALOG:
{
dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
if (dap != NULL)
{
HWND hWndParent;
dap->hWndGeneralPage = hwndDlg;
SetWindowLongPtr(hwndDlg,
DWL_USER,
(DWORD_PTR)dap);
/* subclass the parent window to always receive
WM_DEVICECHANGE messages */
hWndParent = GetParent(hwndDlg);
if (hWndParent != NULL)
{
/* subclass the parent window. This is not safe
if the parent window belongs to another thread! */
dap->ParentOldWndProc = (WNDPROC)SetWindowLongPtr(hWndParent,
GWLP_WNDPROC,
(LONG_PTR)DlgParentSubWndProc);
if (dap->ParentOldWndProc != NULL &&
SetProp(hWndParent,
L"DevMgrDevChangeSub",
(HANDLE)dap))
{
dap->hWndParent = hWndParent;
}
}
/* do not call UpdateDevInfo directly in here because it modifies
the pages of the property sheet! */
PostMessage(hwndDlg,
PM_INITIALIZE,
0,
0);
}
Ret = TRUE;
break;
}
case WM_DEVICECHANGE:
{
/* FIXME - don't call UpdateDevInfo for all events */
UpdateDevInfo(hwndDlg,
dap,
TRUE);
Ret = TRUE;
break;
}
case PM_INITIALIZE:
{
UpdateDevInfo(hwndDlg,
dap,
FALSE);
dap->PageInitialized = TRUE;
break;
}
case WM_DESTROY:
{
/* restore the old window proc of the subclassed parent window */
if (dap->hWndParent != NULL && dap->ParentOldWndProc != NULL)
{
if (SetWindowLongPtr(dap->hWndParent,
GWLP_WNDPROC,
(LONG_PTR)dap->ParentOldWndProc) == (LONG_PTR)DlgParentSubWndProc)
{
RemoveProp(dap->hWndParent,
L"DevMgrDevChangeSub");
}
}
break;
}
}
}
return Ret;
}
INT_PTR
DisplayDeviceAdvancedProperties(IN HWND hWndParent,
IN LPCWSTR lpDeviceID OPTIONAL,
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData,
IN HINSTANCE hComCtl32,
IN LPCWSTR lpMachineName,
IN DWORD dwFlags)
{
PROPSHEETHEADER psh = {0};
PROPSHEETPAGE pspGeneral = {0};
PPROPERTYSHEETW pPropertySheetW;
PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW;
PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage;
PDEVADVPROP_INFO DevAdvPropInfo;
HMACHINE hMachine = NULL;
DWORD DevIdSize = 0;
INT_PTR Ret = -1;
/* we don't want to statically link against comctl32, so find the
functions we need dynamically */
pPropertySheetW =
(PPROPERTYSHEETW)GetProcAddress(hComCtl32,
"PropertySheetW");
pCreatePropertySheetPageW =
(PCREATEPROPERTYSHEETPAGEW)GetProcAddress(hComCtl32,
"CreatePropertySheetPageW");
pDestroyPropertySheetPage =
(PDESTROYPROPERTYSHEETPAGE)GetProcAddress(hComCtl32,
"DestroyPropertySheetPage");
if (pPropertySheetW == NULL ||
pCreatePropertySheetPageW == NULL ||
pDestroyPropertySheetPage == NULL)
{
return -1;
}
if (lpDeviceID == NULL)
{
/* find out how much size is needed for the device id */
if (SetupDiGetDeviceInstanceId(DeviceInfoSet,
DeviceInfoData,
NULL,
0,
&DevIdSize))
{
DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
return -1;
}
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
return -1;
}
}
else
{
DevIdSize = (DWORD)wcslen(lpDeviceID) + 1;
}
if (lpMachineName != NULL && lpMachineName[0] != L'\0')
{
CONFIGRET cr = CM_Connect_Machine(lpMachineName,
&hMachine);
if (cr != CR_SUCCESS)
{
return -1;
}
}
/* create the internal structure associated with the "General",
"Driver", ... pages */
DevAdvPropInfo = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
FIELD_OFFSET(DEVADVPROP_INFO,
szDeviceID) +
(DevIdSize * sizeof(WCHAR)));
if (DevAdvPropInfo == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto Cleanup;
}
if (lpDeviceID == NULL)
{
/* read the device instance id */
if (!SetupDiGetDeviceInstanceId(DeviceInfoSet,
DeviceInfoData,
DevAdvPropInfo->szDeviceID,
DevIdSize,
NULL))
{
goto Cleanup;
}
}
else
{
/* copy the device instance id supplied by the caller */
wcscpy(DevAdvPropInfo->szDeviceID,
lpDeviceID);
}
DevAdvPropInfo->DeviceInfoSet = DeviceInfoSet;
DevAdvPropInfo->DeviceInfoData = *DeviceInfoData;
DevAdvPropInfo->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE;
DevAdvPropInfo->CurrentDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
DevAdvPropInfo->ShowRemotePages = (lpMachineName != NULL && lpMachineName[0] != L'\0');
DevAdvPropInfo->hMachine = hMachine;
DevAdvPropInfo->lpMachineName = lpMachineName;
DevAdvPropInfo->szDevName[0] = L'\0';
DevAdvPropInfo->hComCtl32 = hComCtl32;
DevAdvPropInfo->pCreatePropertySheetPageW = pCreatePropertySheetPageW;
DevAdvPropInfo->pDestroyPropertySheetPage = pDestroyPropertySheetPage;
DevAdvPropInfo->IsAdmin = IsUserAdmin();
DevAdvPropInfo->DoDefaultDevAction = ((dwFlags & DPF_DEVICE_STATUS_ACTION) != 0);
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW;
psh.hwndParent = hWndParent;
psh.pszCaption = DevAdvPropInfo->szDevName;
DevAdvPropInfo->PropertySheetType = DevAdvPropInfo->ShowRemotePages ?
DIGCDP_FLAG_REMOTE_ADVANCED :
DIGCDP_FLAG_ADVANCED;
psh.phpage = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
1 * sizeof(HPROPSHEETPAGE));
if (psh.phpage == NULL)
{
goto Cleanup;
}
/* add the "General" property sheet */
pspGeneral.dwSize = sizeof(PROPSHEETPAGE);
pspGeneral.dwFlags = PSP_DEFAULT;
pspGeneral.hInstance = hDllInstance;
pspGeneral.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEGENERAL);
pspGeneral.pfnDlgProc = AdvPropGeneralDlgProc;
pspGeneral.lParam = (LPARAM)DevAdvPropInfo;
psh.phpage[psh.nPages] = pCreatePropertySheetPageW(&pspGeneral);
if (psh.phpage[psh.nPages] != NULL)
{
psh.nPages++;
}
DevAdvPropInfo->nDevPropSheets = psh.nPages;
if (psh.nPages != 0)
{
Ret = pPropertySheetW(&psh);
/* NOTE: no need to destroy the property sheets anymore! */
}
else
{
UINT i;
Cleanup:
/* in case of failure the property sheets must be destroyed */
if (psh.phpage != NULL)
{
for (i = 0;
i < psh.nPages;
i++)
{
if (psh.phpage[i] != NULL)
{
pDestroyPropertySheetPage(psh.phpage[i]);
}
}
}
}
if (DevAdvPropInfo != NULL)
{
if (DevAdvPropInfo->FreeDevPropSheets)
{
/* don't free the array if it's the one allocated in
DisplayDeviceAdvancedProperties */
HeapFree(GetProcessHeap(),
0,
DevAdvPropInfo->DevPropSheets);
}
if (DevAdvPropInfo->CloseDevInst)
{
/* close the device info set in case a new one was created */
SetupDiDestroyDeviceInfoList(DevAdvPropInfo->DeviceInfoSet);
}
if (DevAdvPropInfo->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
{
SetupDiDestroyDeviceInfoList(DevAdvPropInfo->CurrentDeviceInfoSet);
}
if (DevAdvPropInfo->hDevIcon != NULL)
{
DestroyIcon(DevAdvPropInfo->hDevIcon);
}
HeapFree(GetProcessHeap(),
0,
DevAdvPropInfo);
}
if (psh.phpage != NULL)
{
HeapFree(GetProcessHeap(),
0,
psh.phpage);
}
if (hMachine != NULL)
{
CM_Disconnect_Machine(hMachine);
}
return Ret;
}
static BOOL
GetDeviceAndComputerName(LPWSTR lpString,
WCHAR szDeviceID[],
WCHAR szMachineName[])
{
BOOL ret = FALSE;
szDeviceID[0] = L'\0';
szMachineName[0] = L'\0';
while (*lpString != L'\0')
{
if (*lpString == L'/')
{
lpString++;
if(!wcsnicmp(lpString, L"DeviceID", 8))
{
lpString += 9;
if (*lpString != L'\0')
{
int i = 0;
while ((*lpString != L' ') &&
(*lpString != L'\0') &&
(i <= MAX_DEVICE_ID_LEN))
{
szDeviceID[i++] = *lpString++;
}
szDeviceID[i] = L'\0';
ret = TRUE;
}
}
else if (!wcsnicmp(lpString, L"MachineName", 11))
{
lpString += 12;
if (*lpString != L'\0')
{
int i = 0;
while ((*lpString != L' ') &&
(*lpString != L'\0') &&
(i <= MAX_COMPUTERNAME_LENGTH))
{
szMachineName[i++] = *lpString++;
}
szMachineName[i] = L'\0';
}
}
/* knock the pointer back one and let the next
* pointer deal with incrementing, otherwise we
* go past the end of the string */
lpString--;
}
lpString++;
}
return ret;
}
/***************************************************************************
* NAME EXPORTED
* DeviceAdvancedPropertiesW
*
* DESCRIPTION
* Invokes the device properties dialog, this version may add some property pages
* for some devices
*
* ARGUMENTS
* hWndParent: Handle to the parent window
* lpMachineName: Machine Name, NULL is the local machine
* lpDeviceID: Specifies the device whose properties are to be shown
*
* RETURN VALUE
* Always returns -1, a call to GetLastError returns 0 if successful
*
* @implemented
*/
INT_PTR
WINAPI
DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL,
IN LPCWSTR lpMachineName OPTIONAL,
IN LPCWSTR lpDeviceID)
{
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DevInfoData;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -