mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
1580 lines
43 KiB
C
1580 lines
43 KiB
C
/*
|
|
* Configuration manager functions
|
|
*
|
|
* Copyright 2000 James Hatheway
|
|
* Copyright 2005 Eric Kohl
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "wingdi.h"
|
|
#include "winuser.h"
|
|
#include "winnls.h"
|
|
#include "winreg.h"
|
|
#include "setupapi.h"
|
|
#include "cfgmgr32.h"
|
|
#include "setupapi_private.h"
|
|
|
|
#include "rpc.h"
|
|
#include "rpc_private.h"
|
|
|
|
#include "pnp_c.h"
|
|
|
|
#include "wine/debug.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
|
|
|
|
/* Registry key and value names */
|
|
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};
|
|
|
|
|
|
typedef struct _MACHINE_INFO
|
|
{
|
|
WCHAR szMachineName[MAX_PATH];
|
|
RPC_BINDING_HANDLE BindingHandle;
|
|
HSTRING_TABLE StringTable;
|
|
} MACHINE_INFO, *PMACHINE_INFO;
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Connect_MachineA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Connect_MachineA(PCSTR UNCServerName, PHMACHINE phMachine)
|
|
{
|
|
PWSTR pServerNameW;
|
|
CONFIGRET ret;
|
|
|
|
TRACE("%s %p\n", UNCServerName, phMachine);
|
|
|
|
if (UNCServerName == NULL || *UNCServerName == 0)
|
|
return CM_Connect_MachineW(NULL, phMachine);
|
|
|
|
if (CaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))
|
|
return CR_INVALID_DATA;
|
|
|
|
ret = CM_Connect_MachineW(pServerNameW, phMachine);
|
|
|
|
MyFree(pServerNameW);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Connect_MachineW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Connect_MachineW(PCWSTR UNCServerName, PHMACHINE phMachine)
|
|
{
|
|
PMACHINE_INFO pMachine;
|
|
|
|
TRACE("%s %p\n", debugstr_w(UNCServerName), phMachine);
|
|
|
|
pMachine = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MACHINE_INFO));
|
|
if (pMachine == NULL)
|
|
return CR_OUT_OF_MEMORY;
|
|
|
|
lstrcpyW(pMachine->szMachineName, UNCServerName);
|
|
|
|
pMachine->StringTable = StringTableInitialize();
|
|
if (pMachine->StringTable == NULL)
|
|
{
|
|
HeapFree(GetProcessHeap(), 0, pMachine);
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
StringTableAddString(pMachine->StringTable, L"PLT", 1);
|
|
|
|
if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))
|
|
{
|
|
StringTableDestroy(pMachine->StringTable);
|
|
HeapFree(GetProcessHeap(), 0, pMachine);
|
|
return CR_INVALID_MACHINENAME;
|
|
}
|
|
|
|
phMachine = (PHMACHINE)pMachine;
|
|
|
|
return CR_SUCCESS;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Disconnect_Machine [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Disconnect_Machine(HMACHINE hMachine)
|
|
{
|
|
PMACHINE_INFO pMachine;
|
|
|
|
TRACE("%lx\n", hMachine);
|
|
|
|
pMachine = (PMACHINE_INFO)hMachine;
|
|
if (pMachine == NULL)
|
|
return CR_SUCCESS;
|
|
|
|
if (pMachine->StringTable != NULL)
|
|
StringTableDestroy(pMachine->StringTable);
|
|
|
|
if (!PnpUnbindRpc(pMachine->BindingHandle))
|
|
return CR_ACCESS_DENIED;
|
|
|
|
HeapFree(GetProcessHeap(), 0, pMachine);
|
|
|
|
return CR_SUCCESS;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Enumerate_Classes [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Enumerate_Classes(
|
|
ULONG ulClassIndex, LPGUID ClassGuid, ULONG ulFlags)
|
|
{
|
|
TRACE("%lx %p %lx\n", ulClassIndex, ClassGuid, ulFlags);
|
|
return CM_Enumerate_Classes_Ex(ulClassIndex, ClassGuid, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
static CONFIGRET GetCmCodeFromErrorCode(DWORD ErrorCode)
|
|
{
|
|
switch (ErrorCode)
|
|
{
|
|
case ERROR_SUCCESS:
|
|
return CR_SUCCESS;
|
|
|
|
case ERROR_ACCESS_DENIED:
|
|
return CR_ACCESS_DENIED;
|
|
|
|
case ERROR_INSUFFICIENT_BUFFER:
|
|
return CR_BUFFER_SMALL;
|
|
|
|
case ERROR_INVALID_DATA:
|
|
return CR_INVALID_DATA;
|
|
|
|
case ERROR_INVALID_PARAMETER:
|
|
return CR_INVALID_DATA;
|
|
|
|
case ERROR_NO_MORE_ITEMS:
|
|
return CR_NO_SUCH_VALUE;
|
|
|
|
case ERROR_NO_SYSTEM_RESOURCES:
|
|
return CR_OUT_OF_MEMORY;
|
|
|
|
default:
|
|
return CR_FAILURE;
|
|
}
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Enumerate_Classes_Ex [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Enumerate_Classes_Ex(
|
|
ULONG ulClassIndex, LPGUID ClassGuid, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
HKEY hRelativeKey, hKey;
|
|
DWORD rc;
|
|
WCHAR Buffer[MAX_GUID_STRING_LEN];
|
|
|
|
TRACE("%lx %p %lx %p\n", ulClassIndex, ClassGuid, ulFlags, hMachine);
|
|
|
|
if (ClassGuid == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (ulFlags != 0)
|
|
return CR_INVALID_FLAG;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
FIXME("hMachine argument ignored\n");
|
|
hRelativeKey = HKEY_LOCAL_MACHINE; /* FIXME: use here a field in hMachine */
|
|
}
|
|
else
|
|
hRelativeKey = HKEY_LOCAL_MACHINE;
|
|
|
|
rc = RegOpenKeyExW(
|
|
hRelativeKey,
|
|
ControlClass,
|
|
0, /* options */
|
|
KEY_ENUMERATE_SUB_KEYS,
|
|
&hKey);
|
|
if (rc != ERROR_SUCCESS)
|
|
return GetCmCodeFromErrorCode(rc);
|
|
|
|
rc = RegEnumKeyW(
|
|
hKey,
|
|
ulClassIndex,
|
|
Buffer,
|
|
sizeof(Buffer) / sizeof(WCHAR));
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
if (rc == ERROR_SUCCESS)
|
|
{
|
|
/* Remove the {} */
|
|
Buffer[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
|
|
/* Convert the buffer to a GUID */
|
|
if (UuidFromStringW(&Buffer[1], ClassGuid) != RPC_S_OK)
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
return GetCmCodeFromErrorCode(rc);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Child [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Child(
|
|
PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
|
|
return CM_Get_Child_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Child_Ex [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Child_Ex(
|
|
PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
|
|
RPC_BINDING_HANDLE BindingHandle = NULL;
|
|
HSTRING_TABLE StringTable = NULL;
|
|
LPWSTR lpDevInst;
|
|
DWORD dwIndex;
|
|
CONFIGRET ret;
|
|
|
|
TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
|
|
|
|
if (pdnDevInst == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (dnDevInst == 0)
|
|
return CR_INVALID_DEVINST;
|
|
|
|
if (ulFlags != 0)
|
|
return CR_INVALID_FLAG;
|
|
|
|
*pdnDevInst = -1;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
|
|
if (BindingHandle == NULL)
|
|
return CR_FAILURE;
|
|
|
|
StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
|
|
if (StringTable == 0)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
|
|
if (lpDevInst == NULL)
|
|
return CR_INVALID_DEVNODE;
|
|
|
|
ret = PNP_GetRelatedDeviceInstance(BindingHandle,
|
|
PNP_DEVICE_CHILD,
|
|
lpDevInst,
|
|
szRelatedDevInst,
|
|
MAX_DEVICE_ID_LEN,
|
|
0);
|
|
if (ret != CR_SUCCESS)
|
|
return ret;
|
|
|
|
TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
|
|
|
|
dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
|
|
if (dwIndex == -1)
|
|
return CR_FAILURE;
|
|
|
|
*pdnDevInst = dwIndex;
|
|
|
|
return CR_SUCCESS;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Depth [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Depth(
|
|
PULONG pulDepth, DEVINST dnDevInst, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %lx %lx\n", pulDepth, dnDevInst, ulFlags);
|
|
return CM_Get_Depth_Ex(pulDepth, dnDevInst, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Depth_Ex [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Depth_Ex(
|
|
PULONG pulDepth, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
RPC_BINDING_HANDLE BindingHandle = NULL;
|
|
HSTRING_TABLE StringTable = NULL;
|
|
LPWSTR lpDevInst;
|
|
|
|
TRACE("%p %lx %lx %lx\n",
|
|
pulDepth, dnDevInst, ulFlags, hMachine);
|
|
|
|
if (pulDepth == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (dnDevInst == 0)
|
|
return CR_INVALID_DEVINST;
|
|
|
|
if (ulFlags != 0)
|
|
return CR_INVALID_FLAG;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
|
|
if (BindingHandle == NULL)
|
|
return CR_FAILURE;
|
|
|
|
StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
|
|
if (StringTable == 0)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
|
|
if (lpDevInst == NULL)
|
|
return CR_INVALID_DEVNODE;
|
|
|
|
return PNP_GetDepth(BindingHandle,
|
|
lpDevInst,
|
|
pulDepth,
|
|
ulFlags);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_DevNode_Registry_PropertyA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyA(
|
|
DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
|
|
PVOID Buffer, PULONG pulLength, ULONG ulFlags)
|
|
{
|
|
TRACE("%lx %lu %p %p %p %lx\n",
|
|
dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
|
|
|
|
return CM_Get_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
|
|
pulRegDataType, Buffer,
|
|
pulLength, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_DevNode_Registry_PropertyW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyW(
|
|
DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
|
|
PVOID Buffer, PULONG pulLength, ULONG ulFlags)
|
|
{
|
|
TRACE("%lx %lu %p %p %p %lx\n",
|
|
dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
|
|
|
|
return CM_Get_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
|
|
pulRegDataType, Buffer,
|
|
pulLength, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_DevNode_Registry_Property_ExA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExA(
|
|
DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
|
|
PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
FIXME("%lx %lu %p %p %p %lx %lx\n",
|
|
dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
|
|
ulFlags, hMachine);
|
|
|
|
return CR_CALL_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_DevNode_Registry_Property_ExW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExW(
|
|
DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
|
|
PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
RPC_BINDING_HANDLE BindingHandle = NULL;
|
|
HSTRING_TABLE StringTable = NULL;
|
|
CONFIGRET ret = CR_SUCCESS;
|
|
LPWSTR lpDevInst;
|
|
ULONG ulDataType = 0;
|
|
ULONG ulTransferLength = 0;
|
|
|
|
FIXME("%lx %lu %p %p %p %lx %lx\n",
|
|
dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
|
|
ulFlags, hMachine);
|
|
|
|
if (dnDevInst == 0)
|
|
return CR_INVALID_DEVNODE;
|
|
|
|
if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
|
|
return CR_INVALID_PROPERTY;
|
|
|
|
/* pulRegDataType is optional */
|
|
|
|
/* Buffer is optional */
|
|
|
|
if (pulLength == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (*pulLength == 0)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (ulFlags != 0)
|
|
return CR_INVALID_FLAG;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
|
|
if (BindingHandle == NULL)
|
|
return CR_FAILURE;
|
|
|
|
StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
|
|
if (StringTable == 0)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
|
|
if (lpDevInst == NULL)
|
|
return CR_INVALID_DEVNODE;
|
|
|
|
ulTransferLength = *pulLength;
|
|
ret = PNP_GetDeviceRegProp(BindingHandle,
|
|
lpDevInst,
|
|
ulProperty,
|
|
&ulDataType,
|
|
Buffer,
|
|
&ulTransferLength,
|
|
pulLength,
|
|
ulFlags);
|
|
if (ret == CR_SUCCESS)
|
|
{
|
|
if (pulRegDataType != NULL)
|
|
*pulRegDataType = ulDataType;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_DevNode_Status [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_DevNode_Status(
|
|
PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst,
|
|
ULONG ulFlags)
|
|
{
|
|
TRACE("%p %p %lx %lx\n",
|
|
pulStatus, pulProblemNumber, dnDevInst, ulFlags);
|
|
return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber, dnDevInst,
|
|
ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_DevNode_Status_Ex [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI
|
|
CM_Get_DevNode_Status_Ex(
|
|
PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst,
|
|
ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
RPC_BINDING_HANDLE BindingHandle = NULL;
|
|
HSTRING_TABLE StringTable = NULL;
|
|
LPWSTR lpDevInst;
|
|
|
|
TRACE("%p %p %lx %lx %lx\n",
|
|
pulStatus, pulProblemNumber, dnDevInst, ulFlags, hMachine);
|
|
|
|
if (pulStatus == NULL || pulProblemNumber == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (dnDevInst == 0)
|
|
return CR_INVALID_DEVINST;
|
|
|
|
if (ulFlags != 0)
|
|
return CR_INVALID_FLAG;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
|
|
if (BindingHandle == NULL)
|
|
return CR_FAILURE;
|
|
|
|
StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
|
|
if (StringTable == 0)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
|
|
if (lpDevInst == NULL)
|
|
return CR_INVALID_DEVNODE;
|
|
|
|
return PNP_GetDeviceStatus(BindingHandle,
|
|
lpDevInst,
|
|
pulStatus,
|
|
pulProblemNumber,
|
|
ulFlags);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_IDA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_IDA(
|
|
DEVINST dnDevInst, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
|
|
{
|
|
TRACE("%lx %p %ld %ld\n",
|
|
dnDevInst, Buffer, BufferLen, ulFlags);
|
|
return CM_Get_Device_ID_ExA(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_IDW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_IDW(
|
|
DEVINST dnDevInst, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
|
|
{
|
|
TRACE("%lx %p %ld %ld\n",
|
|
dnDevInst, Buffer, BufferLen, ulFlags);
|
|
return CM_Get_Device_ID_ExW(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_ExA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_ExA(
|
|
DEVINST dnDevInst, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
|
|
HMACHINE hMachine)
|
|
{
|
|
WCHAR szBufferW[MAX_DEVICE_ID_LEN];
|
|
CONFIGRET ret = CR_SUCCESS;
|
|
|
|
FIXME("%lx %p %ld %ld %lx\n",
|
|
dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
|
|
|
|
if (Buffer == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
ret = CM_Get_Device_ID_ExW(dnDevInst,
|
|
szBufferW,
|
|
MAX_DEVICE_ID_LEN,
|
|
ulFlags,
|
|
hMachine);
|
|
if (ret == CR_SUCCESS)
|
|
{
|
|
if (WideCharToMultiByte(CP_ACP,
|
|
0,
|
|
szBufferW,
|
|
lstrlenW(szBufferW) + 1,
|
|
Buffer,
|
|
BufferLen,
|
|
NULL,
|
|
NULL) == 0)
|
|
ret = CR_FAILURE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_ExW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_ExW(
|
|
DEVINST dnDevInst, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
|
|
HMACHINE hMachine)
|
|
{
|
|
HSTRING_TABLE StringTable = NULL;
|
|
|
|
TRACE("%lx %p %ld %ld %lx\n",
|
|
dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
|
|
|
|
if (dnDevInst == 0)
|
|
return CR_INVALID_DEVINST;
|
|
|
|
if (Buffer == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (ulFlags != 0)
|
|
return CR_INVALID_FLAG;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
|
|
if (StringTable == NULL)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(NULL, &StringTable))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
if (!StringTableStringFromIdEx(StringTable,
|
|
dnDevInst,
|
|
Buffer,
|
|
&BufferLen))
|
|
return CR_FAILURE;
|
|
|
|
return CR_SUCCESS;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_ListA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_ListA(
|
|
PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %p %ld %ld\n", pszFilter, Buffer, BufferLen, ulFlags);
|
|
return CM_Get_Device_ID_List_ExA(pszFilter, Buffer, BufferLen,
|
|
ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_ListW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_ListW(
|
|
PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %p %ld %ld\n", pszFilter, Buffer, BufferLen, ulFlags);
|
|
return CM_Get_Device_ID_List_ExW(pszFilter, Buffer, BufferLen,
|
|
ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_List_ExA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_List_ExA(
|
|
PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
|
|
HMACHINE hMachine)
|
|
{
|
|
LPWSTR BufferW = NULL;
|
|
LPWSTR pszFilterW = NULL;
|
|
CONFIGRET ret = CR_SUCCESS;
|
|
|
|
FIXME("%p %p %ld %ld %lx\n",
|
|
pszFilter, Buffer, BufferLen, ulFlags, hMachine);
|
|
|
|
BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
|
|
if (BufferW == NULL)
|
|
return CR_OUT_OF_MEMORY;
|
|
|
|
if (pszFilter == NULL)
|
|
{
|
|
ret = CM_Get_Device_ID_List_ExW(NULL,
|
|
BufferW,
|
|
BufferLen,
|
|
ulFlags,
|
|
hMachine);
|
|
}
|
|
else
|
|
{
|
|
if (CaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
|
|
{
|
|
ret = CR_INVALID_DEVICE_ID;
|
|
goto Done;
|
|
}
|
|
|
|
ret = CM_Get_Device_ID_List_ExW(pszFilterW,
|
|
BufferW,
|
|
BufferLen,
|
|
ulFlags,
|
|
hMachine);
|
|
|
|
MyFree(pszFilterW);
|
|
}
|
|
|
|
if (WideCharToMultiByte(CP_ACP,
|
|
0,
|
|
BufferW,
|
|
lstrlenW(BufferW) + 1,
|
|
Buffer,
|
|
BufferLen,
|
|
NULL,
|
|
NULL) == 0)
|
|
ret = CR_FAILURE;
|
|
|
|
Done:
|
|
MyFree(BufferW);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_List_ExW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_List_ExW(
|
|
PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
|
|
HMACHINE hMachine)
|
|
{
|
|
FIXME("%p %p %ld %ld %lx\n",
|
|
pszFilter, Buffer, BufferLen, ulFlags, hMachine);
|
|
memset(Buffer,0,2);
|
|
return CR_SUCCESS;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_List_SizeA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(
|
|
PULONG pulLen, PCSTR pszFilter, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %s %ld\n", pulLen, pszFilter, ulFlags);
|
|
return CM_Get_Device_ID_List_Size_ExA(pulLen, pszFilter, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_List_SizeW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_List_SizeW(
|
|
PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %s %ld\n", pulLen, debugstr_w(pszFilter), ulFlags);
|
|
return CM_Get_Device_ID_List_Size_ExW(pulLen, pszFilter, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_List_Size_ExA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExA(
|
|
PULONG pulLen, PCSTR pszFilter, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
LPWSTR pszFilterW = NULL;
|
|
CONFIGRET ret = CR_SUCCESS;
|
|
|
|
FIXME("%p %s %lx %lx\n", pulLen, pszFilter, ulFlags, hMachine);
|
|
|
|
if (pszFilter == NULL)
|
|
{
|
|
ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
|
|
NULL,
|
|
ulFlags,
|
|
hMachine);
|
|
}
|
|
else
|
|
{
|
|
if (CaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
|
|
return CR_INVALID_DEVICE_ID;
|
|
|
|
ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
|
|
pszFilterW,
|
|
ulFlags,
|
|
hMachine);
|
|
|
|
MyFree(pszFilterW);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_List_Size_ExW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExW(
|
|
PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
FIXME("%p %s %ld %lx\n", pulLen, debugstr_w(pszFilter), ulFlags, hMachine);
|
|
*pulLen = 2;
|
|
return CR_SUCCESS;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_Size [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_Size(
|
|
PULONG pulLen, DEVINST dnDevInst, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %lx %lx\n", pulLen, dnDevInst, ulFlags);
|
|
return CM_Get_Device_ID_Size_Ex(pulLen, dnDevInst, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Device_ID_Size_Ex [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Device_ID_Size_Ex(
|
|
PULONG pulLen, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
HSTRING_TABLE StringTable = NULL;
|
|
LPWSTR DeviceId;
|
|
|
|
TRACE("%p %lx %lx %lx\n", pulLen, dnDevInst, ulFlags, hMachine);
|
|
|
|
if (pulLen == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (dnDevInst == 0)
|
|
return CR_INVALID_DEVINST;
|
|
|
|
if (ulFlags != 0)
|
|
return CR_INVALID_FLAG;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
|
|
if (StringTable == NULL)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(NULL, &StringTable))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
DeviceId = StringTableStringFromId(StringTable, dnDevInst);
|
|
if (DeviceId == NULL)
|
|
{
|
|
*pulLen = 0;
|
|
return CR_SUCCESS;
|
|
}
|
|
|
|
*pulLen = lstrlenW(DeviceId);
|
|
|
|
return CR_SUCCESS;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Global_State [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Global_State(
|
|
PULONG pulState, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %lx\n", pulState, ulFlags);
|
|
return CM_Get_Global_State_Ex(pulState, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Global_State_Ex [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Global_State_Ex(
|
|
PULONG pulState, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
RPC_BINDING_HANDLE BindingHandle = NULL;
|
|
|
|
TRACE("%p %lx %lx\n", pulState, ulFlags, hMachine);
|
|
|
|
if (pulState == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (ulFlags != 0)
|
|
return CR_INVALID_FLAG;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
|
|
if (BindingHandle == NULL)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(&BindingHandle, NULL))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
return PNP_GetGlobalState(BindingHandle, pulState, ulFlags);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Parent [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Parent(
|
|
PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
|
|
return CM_Get_Parent_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Parent_Ex [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Parent_Ex(
|
|
PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
|
|
RPC_BINDING_HANDLE BindingHandle = NULL;
|
|
HSTRING_TABLE StringTable = NULL;
|
|
LPWSTR lpDevInst;
|
|
DWORD dwIndex;
|
|
CONFIGRET ret;
|
|
|
|
TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
|
|
|
|
if (pdnDevInst == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (dnDevInst == 0)
|
|
return CR_INVALID_DEVINST;
|
|
|
|
if (ulFlags != 0)
|
|
return CR_INVALID_FLAG;
|
|
|
|
*pdnDevInst = -1;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
|
|
if (BindingHandle == NULL)
|
|
return CR_FAILURE;
|
|
|
|
StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
|
|
if (StringTable == 0)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
|
|
if (lpDevInst == NULL)
|
|
return CR_INVALID_DEVNODE;
|
|
|
|
ret = PNP_GetRelatedDeviceInstance(BindingHandle,
|
|
PNP_DEVICE_PARENT,
|
|
lpDevInst,
|
|
szRelatedDevInst,
|
|
MAX_DEVICE_ID_LEN,
|
|
0);
|
|
if (ret != CR_SUCCESS)
|
|
return ret;
|
|
|
|
TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
|
|
|
|
dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
|
|
if (dwIndex == -1)
|
|
return CR_FAILURE;
|
|
|
|
*pdnDevInst = dwIndex;
|
|
|
|
return CR_SUCCESS;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Sibling [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Sibling(
|
|
PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
|
|
return CM_Get_Sibling_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Sibling_Ex [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Get_Sibling_Ex(
|
|
PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
|
|
RPC_BINDING_HANDLE BindingHandle = NULL;
|
|
HSTRING_TABLE StringTable = NULL;
|
|
LPWSTR lpDevInst;
|
|
DWORD dwIndex;
|
|
CONFIGRET ret;
|
|
|
|
TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
|
|
|
|
if (pdnDevInst == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (dnDevInst == 0)
|
|
return CR_INVALID_DEVINST;
|
|
|
|
if (ulFlags != 0)
|
|
return CR_INVALID_FLAG;
|
|
|
|
*pdnDevInst = -1;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
|
|
if (BindingHandle == NULL)
|
|
return CR_FAILURE;
|
|
|
|
StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
|
|
if (StringTable == 0)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
|
|
if (lpDevInst == NULL)
|
|
return CR_INVALID_DEVNODE;
|
|
|
|
ret = PNP_GetRelatedDeviceInstance(BindingHandle,
|
|
PNP_DEVICE_SIBLING,
|
|
lpDevInst,
|
|
szRelatedDevInst,
|
|
MAX_DEVICE_ID_LEN,
|
|
0);
|
|
if (ret != CR_SUCCESS)
|
|
return ret;
|
|
|
|
TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
|
|
|
|
dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
|
|
if (dwIndex == -1)
|
|
return CR_FAILURE;
|
|
|
|
*pdnDevInst = dwIndex;
|
|
|
|
return CR_SUCCESS;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Version [SETUPAPI.@]
|
|
*/
|
|
WORD WINAPI CM_Get_Version(VOID)
|
|
{
|
|
TRACE("\n");
|
|
return CM_Get_Version_Ex(NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Get_Version_Ex [SETUPAPI.@]
|
|
*/
|
|
WORD WINAPI CM_Get_Version_Ex(HMACHINE hMachine)
|
|
{
|
|
RPC_BINDING_HANDLE BindingHandle = NULL;
|
|
WORD Version = 0;
|
|
|
|
TRACE("%lx\n", hMachine);
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
|
|
if (BindingHandle == NULL)
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(&BindingHandle, NULL))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
if (PNP_GetVersion(BindingHandle, &Version) != CR_SUCCESS)
|
|
return 0;
|
|
|
|
return Version;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Locate_DevNodeA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Locate_DevNodeA(
|
|
PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %s %lu\n", pdnDevInst, pDeviceID, ulFlags);
|
|
return CM_Locate_DevNode_ExA(pdnDevInst, pDeviceID, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Locate_DevNodeW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Locate_DevNodeW(
|
|
PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags)
|
|
{
|
|
TRACE("%p %s %lu\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags);
|
|
return CM_Locate_DevNode_ExW(pdnDevInst, pDeviceID, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Locate_DevNode_ExA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Locate_DevNode_ExA(
|
|
PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
DEVINSTID_W pDevIdW = NULL;
|
|
CONFIGRET ret = CR_SUCCESS;
|
|
|
|
TRACE("%p %s %lu %lx\n", pdnDevInst, pDeviceID, ulFlags, hMachine);
|
|
|
|
if (pDeviceID != NULL)
|
|
{
|
|
if (CaptureAndConvertAnsiArg(pDeviceID, &pDevIdW))
|
|
return CR_INVALID_DEVICE_ID;
|
|
}
|
|
|
|
ret = CM_Locate_DevNode_ExW(pdnDevInst, pDevIdW, ulFlags, hMachine);
|
|
|
|
if (pDevIdW != NULL)
|
|
MyFree(pDevIdW);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Locate_DevNode_ExW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Locate_DevNode_ExW(
|
|
PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
WCHAR DeviceIdBuffer[MAX_DEVICE_ID_LEN];
|
|
RPC_BINDING_HANDLE BindingHandle = NULL;
|
|
HSTRING_TABLE StringTable = NULL;
|
|
CONFIGRET ret = CR_SUCCESS;
|
|
|
|
TRACE("%p %s %lu %lx\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags, hMachine);
|
|
|
|
if (pdnDevInst == NULL)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (ulFlags & ~CM_LOCATE_DEVNODE_BITS)
|
|
return CR_INVALID_FLAG;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
|
|
if (BindingHandle == NULL)
|
|
return CR_FAILURE;
|
|
|
|
StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
|
|
if (StringTable == 0)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
if (pDeviceID != NULL && lstrlenW(pDeviceID) != 0)
|
|
{
|
|
lstrcpyW(DeviceIdBuffer, pDeviceID);
|
|
}
|
|
else
|
|
{
|
|
/* Get the root device ID */
|
|
ret = PNP_GetRootDeviceInstance(BindingHandle,
|
|
DeviceIdBuffer,
|
|
MAX_DEVICE_ID_LEN);
|
|
if (ret != CR_SUCCESS)
|
|
return CR_FAILURE;
|
|
}
|
|
TRACE("DeviceIdBuffer: %s\n", debugstr_w(DeviceIdBuffer));
|
|
|
|
/* Validate the device ID */
|
|
ret = PNP_ValidateDeviceInstance(BindingHandle,
|
|
DeviceIdBuffer,
|
|
ulFlags);
|
|
if (ret == CR_SUCCESS)
|
|
{
|
|
*pdnDevInst = StringTableAddString(StringTable, DeviceIdBuffer, 1);
|
|
if (*pdnDevInst == -1)
|
|
ret = CR_FAILURE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Set_DevNode_Problem [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Set_DevNode_Problem(
|
|
DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags)
|
|
{
|
|
TRACE("%lx %lx %lx\n", dnDevInst, ulProblem, ulFlags);
|
|
return CM_Set_DevNode_Problem_Ex(dnDevInst, ulProblem, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Set_DevNode_Problem_Ex [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Set_DevNode_Problem_Ex(
|
|
DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
RPC_BINDING_HANDLE BindingHandle = NULL;
|
|
HSTRING_TABLE StringTable = NULL;
|
|
LPWSTR lpDevInst;
|
|
|
|
TRACE("%lx %lx %lx %lx\n", dnDevInst, ulProblem, ulFlags, hMachine);
|
|
|
|
if (dnDevInst == 0)
|
|
return CR_INVALID_DEVNODE;
|
|
|
|
if (ulFlags & ~CM_SET_DEVNODE_PROBLEM_BITS)
|
|
return CR_INVALID_FLAG;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
|
|
if (BindingHandle == NULL)
|
|
return CR_FAILURE;
|
|
|
|
StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
|
|
if (StringTable == 0)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
|
|
if (lpDevInst == NULL)
|
|
return CR_INVALID_DEVNODE;
|
|
|
|
return PNP_SetDeviceProblem(BindingHandle,
|
|
lpDevInst,
|
|
ulProblem,
|
|
ulFlags);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Set_DevNode_Registry_PropertyA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Set_DevNode_Registry_PropertyA(
|
|
DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
|
|
ULONG ulFlags)
|
|
{
|
|
TRACE("%lx %lu %p %lx %lx\n",
|
|
dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
|
|
return CM_Set_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
|
|
Buffer, ulLength,
|
|
ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Set_DevNode_Registry_PropertyW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Set_DevNode_Registry_PropertyW(
|
|
DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
|
|
ULONG ulFlags)
|
|
{
|
|
TRACE("%lx %lu %p %lx %lx\n",
|
|
dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
|
|
return CM_Set_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
|
|
Buffer, ulLength,
|
|
ulFlags, NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Set_DevNode_Registry_Property_ExA [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Set_DevNode_Registry_Property_ExA(
|
|
DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
|
|
ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
CONFIGRET ret = CR_SUCCESS;
|
|
LPWSTR lpBuffer;
|
|
ULONG ulType;
|
|
|
|
FIXME("%lx %lu %p %lx %lx %lx\n",
|
|
dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
|
|
|
|
if (Buffer == NULL && ulLength != 0)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (Buffer == NULL)
|
|
{
|
|
ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
|
|
ulProperty,
|
|
NULL,
|
|
0,
|
|
ulFlags,
|
|
hMachine);
|
|
}
|
|
else
|
|
{
|
|
/* Get property type */
|
|
switch (ulProperty)
|
|
{
|
|
case CM_DRP_DEVICEDESC:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_HARDWAREID:
|
|
ulType = REG_MULTI_SZ;
|
|
break;
|
|
|
|
case CM_DRP_COMPATIBLEIDS:
|
|
ulType = REG_MULTI_SZ;
|
|
break;
|
|
|
|
case CM_DRP_SERVICE:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_CLASS:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_CLASSGUID:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_DRIVER:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_CONFIGFLAGS:
|
|
ulType = REG_DWORD;
|
|
break;
|
|
|
|
case CM_DRP_MFG:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_FRIENDLYNAME:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_LOCATION_INFORMATION:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_UPPERFILTERS:
|
|
ulType = REG_MULTI_SZ;
|
|
break;
|
|
|
|
case CM_DRP_LOWERFILTERS:
|
|
ulType = REG_MULTI_SZ;
|
|
break;
|
|
|
|
default:
|
|
return CR_INVALID_PROPERTY;
|
|
}
|
|
|
|
/* Allocate buffer if needed */
|
|
if (ulType == REG_SZ ||
|
|
ulType == REG_MULTI_SZ)
|
|
{
|
|
lpBuffer = MyMalloc(ulLength * sizeof(WCHAR));
|
|
if (lpBuffer == NULL)
|
|
{
|
|
ret = CR_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
if (!MultiByteToWideChar(CP_ACP, 0, Buffer,
|
|
ulLength, lpBuffer, ulLength))
|
|
{
|
|
MyFree(lpBuffer);
|
|
ret = CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
|
|
ulProperty,
|
|
lpBuffer,
|
|
ulLength * sizeof(WCHAR),
|
|
ulFlags,
|
|
hMachine);
|
|
MyFree(lpBuffer);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
|
|
ulProperty,
|
|
Buffer,
|
|
ulLength,
|
|
ulFlags,
|
|
hMachine);
|
|
}
|
|
|
|
ret = CR_CALL_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CM_Set_DevNode_Registry_Property_ExW [SETUPAPI.@]
|
|
*/
|
|
CONFIGRET WINAPI CM_Set_DevNode_Registry_Property_ExW(
|
|
DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
|
|
ULONG ulFlags, HMACHINE hMachine)
|
|
{
|
|
RPC_BINDING_HANDLE BindingHandle = NULL;
|
|
HSTRING_TABLE StringTable = NULL;
|
|
LPWSTR lpDevInst;
|
|
ULONG ulType;
|
|
|
|
TRACE("%lx %lu %p %lx %lx %lx\n",
|
|
dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
|
|
|
|
if (dnDevInst == 0)
|
|
return CR_INVALID_DEVNODE;
|
|
|
|
if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
|
|
return CR_INVALID_PROPERTY;
|
|
|
|
if (Buffer != NULL && ulLength == 0)
|
|
return CR_INVALID_POINTER;
|
|
|
|
if (ulFlags != 0)
|
|
return CR_INVALID_FLAG;
|
|
|
|
if (hMachine != NULL)
|
|
{
|
|
BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
|
|
if (BindingHandle == NULL)
|
|
return CR_FAILURE;
|
|
|
|
StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
|
|
if (StringTable == 0)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
|
|
return CR_FAILURE;
|
|
}
|
|
|
|
lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
|
|
if (lpDevInst == NULL)
|
|
return CR_INVALID_DEVNODE;
|
|
|
|
switch (ulProperty)
|
|
{
|
|
case CM_DRP_DEVICEDESC:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_HARDWAREID:
|
|
ulType = REG_MULTI_SZ;
|
|
break;
|
|
|
|
case CM_DRP_COMPATIBLEIDS:
|
|
ulType = REG_MULTI_SZ;
|
|
break;
|
|
|
|
case CM_DRP_SERVICE:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_CLASS:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_CLASSGUID:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_DRIVER:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_CONFIGFLAGS:
|
|
ulType = REG_DWORD;
|
|
break;
|
|
|
|
case CM_DRP_MFG:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_FRIENDLYNAME:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_LOCATION_INFORMATION:
|
|
ulType = REG_SZ;
|
|
break;
|
|
|
|
case CM_DRP_UPPERFILTERS:
|
|
ulType = REG_MULTI_SZ;
|
|
break;
|
|
|
|
case CM_DRP_LOWERFILTERS:
|
|
ulType = REG_MULTI_SZ;
|
|
break;
|
|
|
|
default:
|
|
return CR_INVALID_PROPERTY;
|
|
}
|
|
|
|
return PNP_SetDeviceRegProp(BindingHandle,
|
|
lpDevInst,
|
|
ulProperty,
|
|
ulType,
|
|
(char *)Buffer,
|
|
ulLength,
|
|
ulFlags);
|
|
}
|