From 624151b290df4f2839ab439ecc9db31d15389158 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 28 Aug 2005 15:07:45 +0000 Subject: [PATCH] Implement CM_Get_Class_Key_Name[_Ex]A/W and CM_Open_Class[_Ex]A/W. svn path=/trunk/; revision=17586 --- reactos/include/idl/pnp.idl | 6 + reactos/include/wine/cfgmgr32.h | 7 +- reactos/lib/setupapi/cfgmgr.c | 236 ++++++++++++++++++++++++++ reactos/lib/setupapi/setupapi.spec | 16 +- reactos/services/umpnpmgr/umpnpmgr.c | 49 ++++++ reactos/w32api/include/ddk/cfgmgr32.h | 110 +++++++++++- 6 files changed, 409 insertions(+), 15 deletions(-) diff --git a/reactos/include/idl/pnp.idl b/reactos/include/idl/pnp.idl index 283512b8c1f..c208c22d38f 100644 --- a/reactos/include/idl/pnp.idl +++ b/reactos/include/idl/pnp.idl @@ -69,6 +69,12 @@ interface pnp [in] unsigned long Length, [in] unsigned long Flags); + CONFIGRET PNP_GetClassName(handle_t BindingHandle, + [in, string] wchar_t *ClassGuid, + [out, string, size_is(*Length)] wchar_t *Buffer, + [in, out] unsigned long *Length, + [in] unsigned long Flags); + CONFIGRET PNP_GetDeviceStatus(handle_t BindingHandle, [in, string] wchar_t *DeviceInstance, [out] unsigned long *Status, diff --git a/reactos/include/wine/cfgmgr32.h b/reactos/include/wine/cfgmgr32.h index acbfa510581..dc78f389481 100644 --- a/reactos/include/wine/cfgmgr32.h +++ b/reactos/include/wine/cfgmgr32.h @@ -128,12 +128,17 @@ DECL_WINELIB_CFGMGR32_TYPE_AW(DEVINSTID) CONFIGRET WINAPI CM_Connect_MachineA( PCSTR, PHMACHINE ); CONFIGRET WINAPI CM_Connect_MachineW( PCWSTR, PHMACHINE ); #define CM_Connect_Machine WINELIB_NAME_AW(CM_Connect_Machine) - CONFIGRET WINAPI CM_Disconnect_Machine( HMACHINE ); CONFIGRET WINAPI CM_Enumerate_Classes( ULONG, LPGUID, ULONG ); CONFIGRET WINAPI CM_Enumerate_Classes_Ex( ULONG, LPGUID, ULONG, HMACHINE ); CONFIGRET WINAPI CM_Get_Child( PDEVINST, DEVINST, ULONG ); CONFIGRET WINAPI CM_Get_Child_Ex( PDEVINST, DEVINST, ULONG, HMACHINE ); +CONFIGRET WINAPI CM_Get_Class_Key_NameA( LPGUID, LPSTR, PULONG, ULONG ); +CONFIGRET WINAPI CM_Get_Class_Key_NameW( LPGUID, LPWSTR, PULONG, ULONG ); +#define CM_Get_Class_Key_Name WINELIB_NAME_AW(CM_Get_Class_Key_Name) +CONFIGRET WINAPI CM_Get_Class_Key_Name_ExA( LPGUID, LPSTR, PULONG, ULONG, HMACHINE ); +CONFIGRET WINAPI CM_Get_Class_Key_Name_ExW( LPGUID, LPWSTR, PULONG, ULONG, HMACHINE ); +#define CM_Get_Class_Key_Name_Ex WINELIB_NAME_AW(CM_Get_Class_Key_Name_Ex) CONFIGRET WINAPI CM_Get_Depth( PULONG, DEVINST, ULONG ); CONFIGRET WINAPI CM_Get_Depth_Ex( PULONG, DEVINST, ULONG, HMACHINE ); CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyA( DEVINST, ULONG, PULONG, PVOID, PULONG, ULONG ); diff --git a/reactos/lib/setupapi/cfgmgr.c b/reactos/lib/setupapi/cfgmgr.c index f3f3f850a9e..bc6068b60b8 100644 --- a/reactos/lib/setupapi/cfgmgr.c +++ b/reactos/lib/setupapi/cfgmgr.c @@ -41,11 +41,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(setupapi); /* Registry key and value names */ +static const WCHAR Backslash[] = {'\\', 0}; +static const WCHAR Class[] = {'C','l','a','s','s',0}; + static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\', 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', 'C','o','n','t','r','o','l','\\', 'C','l','a','s','s',0}; +static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\', + 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', + 'C','o','n','t','r','o','l','\\', + 'D','e','v','i','c','e','C','l','a','s','s','e','s',0}; typedef struct _MACHINE_INFO { @@ -317,6 +324,76 @@ CONFIGRET WINAPI CM_Get_Child_Ex( } +/*********************************************************************** + * CM_Get_Class_Key_NameA [SETUPAPI.@] + */ +CONFIGRET WINAPI CM_Get_Class_Key_NameA( + LPGUID ClassGuid, LPSTR pszKeyName, PULONG pulLength, ULONG ulFlags) +{ + TRACE("%p %p %p %lx\n", + ClassGuid, pszKeyName, pulLength, ulFlags); + return CM_Get_Class_Key_Name_ExA(ClassGuid, pszKeyName, pulLength, + ulFlags, NULL); +} + + +/*********************************************************************** + * CM_Get_Class_Key_NameW [SETUPAPI.@] + */ +CONFIGRET WINAPI CM_Get_Class_Key_NameW( + LPGUID ClassGuid, LPWSTR pszKeyName, PULONG pulLength, ULONG ulFlags) +{ + TRACE("%p %p %p %lx\n", + ClassGuid, pszKeyName, pulLength, ulFlags); + return CM_Get_Class_Key_Name_ExW(ClassGuid, pszKeyName, pulLength, + ulFlags, NULL); +} + + +/*********************************************************************** + * CM_Get_Class_Key_Name_ExA [SETUPAPI.@] + */ +CONFIGRET WINAPI CM_Get_Class_Key_Name_ExA( + LPGUID ClassGuid, LPSTR pszKeyName, PULONG pulLength, ULONG ulFlags, + HMACHINE hMachine) +{ + FIXME("%p %p %p %lx %lx\n", + ClassGuid, pszKeyName, pulLength, ulFlags, hMachine); + return CR_FAILURE; +} + + +/*********************************************************************** + * CM_Get_Class_Key_Name_ExW [SETUPAPI.@] + */ +CONFIGRET WINAPI CM_Get_Class_Key_Name_ExW( + LPGUID ClassGuid, LPWSTR pszKeyName, PULONG pulLength, ULONG ulFlags, + HMACHINE hMachine) +{ + FIXME("%p %p %p %lx %lx\n", + ClassGuid, pszKeyName, pulLength, ulFlags, hMachine); + + if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL) + return CR_INVALID_POINTER; + + if (ulFlags != 0) + return CR_INVALID_FLAG; + + if (*pulLength < MAX_GUID_STRING_LEN) + { + *pulLength = 0; + return CR_BUFFER_SMALL; + } + + if (UuidToStringW(ClassGuid, &pszKeyName) != RPC_S_OK) + return CR_INVALID_DATA; + + *pulLength = MAX_GUID_STRING_LEN; + + return CR_SUCCESS; +} + + /*********************************************************************** * CM_Get_Depth [SETUPAPI.@] */ @@ -1245,6 +1322,165 @@ CONFIGRET WINAPI CM_Locate_DevNode_ExW( } +/*********************************************************************** + * CM_Open_Class_KeyA [SETUPAPI.@] + */ +CONFIGRET WINAPI CM_Open_Class_KeyA( + LPGUID pClassGuid, LPCSTR pszClassName, REGSAM samDesired, + REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags) +{ + TRACE("%p %s %lx %lx %p %lx\n", + debugstr_guid(pClassGuid), pszClassName, + samDesired, Disposition, phkClass, ulFlags); + + return CM_Open_Class_Key_ExA(pClassGuid, pszClassName, samDesired, + Disposition, phkClass, ulFlags, NULL); +} + + +/*********************************************************************** + * CM_Open_Class_KeyW [SETUPAPI.@] + */ +CONFIGRET WINAPI CM_Open_Class_KeyW( + LPGUID pClassGuid, LPCWSTR pszClassName, REGSAM samDesired, + REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags) +{ + TRACE("%p %s %lx %lx %p %lx\n", + debugstr_guid(pClassGuid), debugstr_w(pszClassName), + samDesired, Disposition, phkClass, ulFlags); + + return CM_Open_Class_Key_ExW(pClassGuid, pszClassName, samDesired, + Disposition, phkClass, ulFlags, NULL); +} + + +/*********************************************************************** + * CM_Open_Class_Key_ExA [SETUPAPI.@] + */ +CONFIGRET WINAPI CM_Open_Class_Key_ExA( + LPGUID pClassGuid, LPCSTR pszClassName, REGSAM samDesired, + REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags, + HMACHINE hMachine) +{ + CONFIGRET rc = CR_SUCCESS; + LPWSTR pszClassNameW = NULL; + + TRACE("%p %s %lx %lx %p %lx %lx\n", + debugstr_guid(pClassGuid), pszClassName, + samDesired, Disposition, phkClass, ulFlags, hMachine); + + if (pszClassName != NULL) + { + if (CaptureAndConvertAnsiArg(pszClassName, &pszClassNameW)) + return CR_INVALID_DATA; + } + + rc = CM_Open_Class_Key_ExW(pClassGuid, pszClassNameW, samDesired, + Disposition, phkClass, ulFlags, hMachine); + + if (pszClassNameW != NULL) + MyFree(pszClassNameW); + + return CR_SUCCESS; +} + + +/*********************************************************************** + * CM_Open_Class_Key_ExW [SETUPAPI.@] + */ +CONFIGRET WINAPI CM_Open_Class_Key_ExW( + LPGUID pClassGuid, LPCWSTR pszClassName, REGSAM samDesired, + REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags, + HMACHINE hMachine) +{ + WCHAR szKeyName[MAX_PATH]; + LPWSTR lpGuidString; + DWORD dwDisposition; + DWORD dwError; + HKEY hKey; + + TRACE("%p %s %lx %lx %p %lx %lx\n", + debugstr_guid(pClassGuid), debugstr_w(pszClassName), + samDesired, Disposition, phkClass, ulFlags, hMachine); + + /* Check Disposition and ulFlags */ + if ((Disposition & ~RegDisposition_Bits) || + (ulFlags & ~CM_OPEN_CLASS_KEY_BITS)) + return CR_INVALID_FLAG; + + /* Check phkClass */ + if (phkClass == NULL) + return CR_INVALID_POINTER; + + *phkClass = NULL; + + if (ulFlags == CM_OPEN_CLASS_KEY_INTERFACE && + pszClassName != NULL) + return CR_INVALID_DATA; + + if (hMachine == NULL) + { + hKey = HKEY_LOCAL_MACHINE; + } + else + { + if (RegConnectRegistryW(((PMACHINE_INFO)hMachine)->szMachineName, + HKEY_LOCAL_MACHINE, &hKey)) + return CR_REGISTRY_ERROR; + } + + if (ulFlags & CM_OPEN_CLASS_KEY_INTERFACE) + { + lstrcpyW(szKeyName, DeviceClasses); + } + else + { + lstrcpyW(szKeyName, ControlClass); + } + + if (pClassGuid != NULL) + { + if (UuidToStringW((UUID*)pClassGuid, &lpGuidString) != RPC_S_OK) + { + RegCloseKey(hKey); + return CR_INVALID_DATA; + } + + lstrcatW(szKeyName, Backslash); + lstrcatW(szKeyName, lpGuidString); + } + + if (Disposition == RegDisposition_OpenAlways) + { + dwError = RegCreateKeyExW(hKey, szKeyName, 0, NULL, 0, samDesired, + NULL, phkClass, &dwDisposition); + } + else + { + dwError = RegOpenKeyExW(hKey, szKeyName, 0, samDesired, phkClass); + } + + RegCloseKey(hKey); + + if (pClassGuid != NULL) + RpcStringFreeW(&lpGuidString); + + if (dwError != ERROR_SUCCESS) + { + *phkClass = NULL; + return CR_NO_SUCH_REGISTRY_KEY; + } + + if (pszClassName != NULL) + { + RegSetValueExW(*phkClass, Class, 0, REG_SZ, (LPBYTE)pszClassName, + (lstrlenW(pszClassName) + 1) * sizeof(WCHAR)); + } + + return CR_SUCCESS; +} + + /*********************************************************************** * CM_Set_DevNode_Problem [SETUPAPI.@] */ diff --git a/reactos/lib/setupapi/setupapi.spec b/reactos/lib/setupapi/setupapi.spec index d36fe8fd565..bd7c5098361 100644 --- a/reactos/lib/setupapi/setupapi.spec +++ b/reactos/lib/setupapi/setupapi.spec @@ -55,10 +55,10 @@ @ stub CM_Free_Res_Des_Handle @ stdcall CM_Get_Child(ptr long long) @ stdcall CM_Get_Child_Ex(ptr long long long) -@ stub CM_Get_Class_Key_NameA -@ stub CM_Get_Class_Key_NameW -@ stub CM_Get_Class_Key_Name_ExA -@ stub CM_Get_Class_Key_Name_ExW +@ stdcall CM_Get_Class_Key_NameA(ptr str ptr long) +@ stdcall CM_Get_Class_Key_NameW(ptr wstr ptr long) +@ stdcall CM_Get_Class_Key_Name_ExA(ptr str ptr long long) +@ stdcall CM_Get_Class_Key_Name_ExW(ptr wstr ptr long long) @ stub CM_Get_Class_NameA @ stub CM_Get_Class_NameW @ stub CM_Get_Class_Name_ExA @@ -139,10 +139,10 @@ @ stub CM_Move_DevNode @ stub CM_Move_DevNode_Ex @ stub CM_Next_Range -@ stub CM_Open_Class_KeyA -@ stub CM_Open_Class_KeyW -@ stub CM_Open_Class_Key_ExA -@ stub CM_Open_Class_Key_ExW +@ stdcall CM_Open_Class_KeyA(ptr str long long ptr long) +@ stdcall CM_Open_Class_KeyW(ptr wstr long long ptr long) +@ stdcall CM_Open_Class_Key_ExA(ptr str long long ptr long long) +@ stdcall CM_Open_Class_Key_ExW(ptr wstr long long ptr long long) @ stub CM_Open_DevNode_Key @ stub CM_Open_DevNode_Key_Ex @ stub CM_Query_Arbitrator_Free_Data diff --git a/reactos/services/umpnpmgr/umpnpmgr.c b/reactos/services/umpnpmgr/umpnpmgr.c index 80c2d02525a..2efcc9e504b 100644 --- a/reactos/services/umpnpmgr/umpnpmgr.c +++ b/reactos/services/umpnpmgr/umpnpmgr.c @@ -634,6 +634,55 @@ PNP_GetDeviceRegProp(handle_t BindingHandle, } +CONFIGRET +PNP_GetClassName(handle_t BindingHandle, + wchar_t *ClassGuid, /* in */ + wchar_t *Buffer, /* out */ + unsigned long *Length, /* in out */ + unsigned long Flags) +{ + WCHAR szKeyName[MAX_PATH]; + CONFIGRET ret = CR_SUCCESS; + HKEY hKey = NULL; + ULONG ulSize; + + DPRINT1("PNP_GetClassName() called\n"); + + lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class"); + lstrcatW(szKeyName, L"\\"); + lstrcatW(szKeyName, ClassGuid); + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, + szKeyName, + 0, + KEY_QUERY_VALUE, + &hKey)) + return CR_REGISTRY_ERROR; + + ulSize = *Length * sizeof(WCHAR); + if (RegQueryValueExW(hKey, + L"Class", + NULL, + NULL, + (LPBYTE)Buffer, + &ulSize)) + { + *Length = 0; + ret = CR_REGISTRY_ERROR; + } + else + { + *Length = ulSize / sizeof(WCHAR); + } + + RegCloseKey(hKey); + + DPRINT1("PNP_GetClassName() done (returns %lx)\n", ret); + + return ret; +} + + CONFIGRET PNP_GetDeviceStatus(handle_t BindingHandle, wchar_t *DeviceInstance, diff --git a/reactos/w32api/include/ddk/cfgmgr32.h b/reactos/w32api/include/ddk/cfgmgr32.h index cf6e85791ad..d8f802ea90e 100644 --- a/reactos/w32api/include/ddk/cfgmgr32.h +++ b/reactos/w32api/include/ddk/cfgmgr32.h @@ -787,7 +787,7 @@ CM_Enumerate_EnumeratorsW( #define CM_Enumerate_Enumerators_Ex CM_Enumerate_Enumerators_ExW #else #define CM_Enumerate_Enumerators CM_Enumerate_EnumeratorsA -#define CM_Enumerate_Enumerators_Ex CM_Enumerate_Enumerators_ExW +#define CM_Enumerate_Enumerators_Ex CM_Enumerate_Enumerators_ExA #endif /* UNICODE */ /* FIXME: Obsolete CM_Find_Range */ @@ -864,8 +864,53 @@ CM_Get_Child_Ex( /* FIXME: Obsolete CM_Get_Class_Name */ /* FIXME: Obsolete CM_Get_Class_Name_Ex */ -/* FIXME: Obsolete CM_Get_Class_Key_Name */ -/* FIXME: Obsolete CM_Get_Class_Key_Name_Ex */ + +CMAPI +CONFIGRET +WINAPI +CM_Get_Class_Key_NameA( + IN LPGUID ClassGuid, + OUT LPSTR pszKeyName, + IN OUT PULONG pulLength, + IN ULONG ulFlags); + +CMAPI +CONFIGRET +WINAPI +CM_Get_Class_Key_NameW( + IN LPGUID ClassGuid, + OUT LPWSTR pszKeyName, + IN OUT PULONG pulLength, + IN ULONG ulFlags); + +CMAPI +CONFIGRET +WINAPI +CM_Get_Class_Key_Name_ExA( + IN LPGUID ClassGuid, + OUT LPSTR pszKeyName, + IN OUT PULONG pulLength, + IN ULONG ulFlags, + IN HMACHINE hMachine); + +CMAPI +CONFIGRET +WINAPI +CM_Get_Class_Key_Name_ExW( + IN LPGUID ClassGuid, + OUT LPWSTR pszKeyName, + IN OUT PULONG pulLength, + IN ULONG ulFlags, + IN HMACHINE hMachine); + +#ifdef UNICODE +#define CM_Get_Class_Key_Name CM_Get_Class_Key_NameW +#define CM_Get_Class_Key_Name_Ex CM_Get_Class_Key_Name_ExW +#else +#define CM_Get_Class_Key_Name CM_Get_Class_Key_NameA +#define CM_Get_Class_Key_Name_Ex CM_Get_Class_Key_Name_ExA +#endif /* UNICODE */ + /* FIXME: Obsolete CM_Get_Class_Registry_Property */ CMAPI @@ -928,7 +973,7 @@ CM_Get_Device_IDW( #define CM_Get_Device_ID_Ex CM_Get_Device_ID_ExW #else #define CM_Get_Device_ID CM_Get_Device_IDA -#define CM_Get_Device_ID_Ex CM_Get_Device_ID_ExW +#define CM_Get_Device_ID_Ex CM_Get_Device_ID_ExA #endif /* UNICODE */ CMAPI @@ -1440,8 +1485,61 @@ CM_Modify_Res_Des_Ex( /* FIXME: Obsolete CM_Move_DevNode */ /* FIXME: Obsolete CM_Move_DevNode_Ex */ /* FIXME: Obsolete CM_Next_Range */ -/* FIXME: Obsolete CM_Open_Class_Key */ -/* FIXME: Obsolete CM_Open_Class_Key_Ex */ + +CMAPI +CONFIGRET +WINAPI +CM_Open_Class_KeyA( + IN LPGUID ClassGuid, OPTIONAL + IN LPCSTR pszClassName, OPTIONAL + IN REGSAM samDesired, + IN REGDISPOSITION Disposition, + OUT PHKEY phkClass, + IN ULONG ulFlags); + +CMAPI +CONFIGRET +WINAPI +CM_Open_Class_KeyW( + IN LPGUID ClassGuid, OPTIONAL + IN LPCWSTR pszClassName, OPTIONAL + IN REGSAM samDesired, + IN REGDISPOSITION Disposition, + OUT PHKEY phkClass, + IN ULONG ulFlags); + +CMAPI +CONFIGRET +WINAPI +CM_Open_Class_Key_ExA( + IN LPGUID pszClassGuid, OPTIONAL + IN LPCSTR pszClassName, OPTIONAL + IN REGSAM samDesired, + IN REGDISPOSITION Disposition, + OUT PHKEY phkClass, + IN ULONG ulFlags, + IN HMACHINE hMachine); + +CMAPI +CONFIGRET +WINAPI +CM_Open_Class_Key_ExW( + IN LPGUID pszClassGuid, OPTIONAL + IN LPCWSTR pszClassName, OPTIONAL + IN REGSAM samDesired, + IN REGDISPOSITION Disposition, + OUT PHKEY phkClass, + IN ULONG ulFlags, + IN HMACHINE hMachine); + +#ifdef UNICODE +#define CM_Open_Class_Key CM_Open_Class_KeyW +#define CM_Open_Class_Key_Ex CM_Open_Class_Key_ExW +#else +#define CM_Open_Class_Key CM_Open_Class_KeyA +#define CM_Open_Class_Key_Ex CM_Open_Class_Key_ExA +#endif /* UNICODE */ + /* FIXME: Obsolete CM_Open_DevNode_Key */ /* FIXME: Obsolete CM_Open_DevNode_Key_Ex */