ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cfgmgr.c
Go to the documentation of this file.
00001 /*
00002  * Configuration manager functions
00003  *
00004  * Copyright 2000 James Hatheway
00005  * Copyright 2005, 2006 Eric Kohl
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include "setupapi_private.h"
00023 
00024 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
00025 
00026 /* Registry key and value names */
00027 static const WCHAR Backslash[] = {'\\', 0};
00028 static const WCHAR Class[]  = {'C','l','a','s','s',0};
00029 
00030 static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
00031                                      'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
00032                                      'C','o','n','t','r','o','l','\\',
00033                                      'C','l','a','s','s',0};
00034 
00035 static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
00036                                       'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
00037                                       'C','o','n','t','r','o','l','\\',
00038                                       'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
00039 
00040 typedef struct _MACHINE_INFO
00041 {
00042     WCHAR szMachineName[SP_MAX_MACHINENAME_LENGTH];
00043     RPC_BINDING_HANDLE BindingHandle;
00044     HSTRING_TABLE StringTable;
00045     BOOL bLocal;
00046 } MACHINE_INFO, *PMACHINE_INFO;
00047 
00048 
00049 typedef struct _LOG_CONF_INFO
00050 {
00051     ULONG ulMagic;
00052     DEVINST dnDevInst;
00053     ULONG ulFlags;
00054     ULONG ulTag;
00055 } LOG_CONF_INFO, *PLOG_CONF_INFO;
00056 
00057 #define LOG_CONF_MAGIC 0x464E434C  /* "LCNF" */
00058 
00059 
00060 static BOOL GuidToString(LPGUID Guid, LPWSTR String)
00061 {
00062     LPWSTR lpString;
00063 
00064     if (UuidToStringW(Guid, &lpString) != RPC_S_OK)
00065         return FALSE;
00066 
00067     lstrcpyW(&String[1], lpString);
00068 
00069     String[0] = '{';
00070     String[MAX_GUID_STRING_LEN - 2] = '}';
00071     String[MAX_GUID_STRING_LEN - 1] = UNICODE_NULL;
00072 
00073     RpcStringFreeW(&lpString);
00074 
00075     return TRUE;
00076 }
00077 
00078 
00079 static CONFIGRET
00080 RpcStatusToCmStatus(RPC_STATUS Status)
00081 {
00082     return CR_FAILURE;
00083 }
00084 
00085 
00086 /***********************************************************************
00087  * CMP_Init_Detection [SETUPAPI.@]
00088  */
00089 CONFIGRET WINAPI CMP_Init_Detection(
00090     DWORD dwMagic)
00091 {
00092     RPC_BINDING_HANDLE BindingHandle = NULL;
00093     CONFIGRET ret;
00094 
00095     TRACE("%lu\n", dwMagic);
00096 
00097     if (dwMagic != CMP_MAGIC)
00098         return CR_INVALID_DATA;
00099 
00100     if (!PnpGetLocalHandles(&BindingHandle, NULL))
00101         return CR_FAILURE;
00102 
00103     RpcTryExcept
00104     {
00105         ret = PNP_InitDetection(BindingHandle);
00106     }
00107     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
00108     {
00109         ret = RpcStatusToCmStatus(RpcExceptionCode());
00110     }
00111     RpcEndExcept;
00112 
00113     return ret;
00114 }
00115 
00116 
00117 /***********************************************************************
00118  * CMP_RegisterNotification [SETUPAPI.@]
00119  */
00120 CONFIGRET
00121 WINAPI
00122 CMP_RegisterNotification(IN HANDLE hRecipient,
00123                          IN LPVOID lpvNotificationFilter,
00124                          IN DWORD dwFlags,
00125                          OUT PULONG pluhDevNotify)
00126 {
00127     FIXME("Stub %p %p %lu %p\n", hRecipient, lpvNotificationFilter, dwFlags, pluhDevNotify);
00128     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00129     return CR_FAILURE;
00130 }
00131 
00132 
00133 /***********************************************************************
00134  * CMP_Report_LogOn [SETUPAPI.@]
00135  */
00136 CONFIGRET WINAPI CMP_Report_LogOn(
00137     DWORD dwMagic,
00138     DWORD dwProcessId)
00139 {
00140     RPC_BINDING_HANDLE BindingHandle = NULL;
00141     CONFIGRET ret = CR_SUCCESS;
00142     BOOL bAdmin;
00143     DWORD i;
00144 
00145     TRACE("%lu\n", dwMagic);
00146 
00147     if (dwMagic != CMP_MAGIC)
00148         return CR_INVALID_DATA;
00149 
00150     if (!PnpGetLocalHandles(&BindingHandle, NULL))
00151         return CR_FAILURE;
00152 
00153     bAdmin = pSetupIsUserAdmin();
00154 
00155     for (i = 0; i < 30; i++)
00156     {
00157         RpcTryExcept
00158         {
00159             ret = PNP_ReportLogOn(BindingHandle,
00160                                   bAdmin,
00161                                   dwProcessId);
00162         }
00163         RpcExcept(EXCEPTION_EXECUTE_HANDLER)
00164         {
00165             ret = RpcStatusToCmStatus(RpcExceptionCode());
00166         }
00167         RpcEndExcept;
00168 
00169         if (ret == CR_SUCCESS)
00170             break;
00171 
00172         Sleep(5000);
00173     }
00174 
00175     return ret;
00176 }
00177 
00178 
00179 /***********************************************************************
00180  * CMP_UnregisterNotification [SETUPAPI.@]
00181  */
00182 CONFIGRET
00183 WINAPI
00184 CMP_UnregisterNotification(IN HDEVNOTIFY handle)
00185 {
00186     FIXME("Stub %p\n", handle);
00187     return CR_SUCCESS;
00188 }
00189 
00190 
00191 /***********************************************************************
00192  * CMP_WaitNoPendingInstallEvents [SETUPAPI.@]
00193  */
00194 DWORD WINAPI CMP_WaitNoPendingInstallEvents(
00195     DWORD dwTimeout)
00196 {
00197     HANDLE hEvent;
00198     DWORD ret;
00199 
00200     hEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\PnP_No_Pending_Install_Events");
00201     if (hEvent == NULL)
00202        return WAIT_FAILED;
00203 
00204     ret = WaitForSingleObject(hEvent, dwTimeout);
00205     CloseHandle(hEvent);
00206     return ret;
00207 }
00208 
00209 
00210 /***********************************************************************
00211  * CMP_WaitServicesAvailable [SETUPAPI.@]
00212  */
00213 CONFIGRET
00214 WINAPI
00215 CMP_WaitServicesAvailable(HMACHINE hMachine)
00216 {
00217     RPC_BINDING_HANDLE BindingHandle = NULL;
00218     CONFIGRET ret = CR_SUCCESS;
00219     WORD Version;
00220 
00221     if (!PnpGetLocalHandles(&BindingHandle, NULL))
00222         return CR_FAILURE;
00223 
00224     RpcTryExcept
00225     {
00226         ret = PNP_GetVersion(BindingHandle, &Version);
00227     }
00228     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
00229     {
00230         ret = RpcStatusToCmStatus(RpcExceptionCode());
00231     }
00232     RpcEndExcept;
00233 
00234     return ret;
00235 }
00236 
00237 
00238 /***********************************************************************
00239  * CM_Add_Empty_Log_Conf [SETUPAPI.@]
00240  */
00241 CONFIGRET WINAPI CM_Add_Empty_Log_Conf(
00242     PLOG_CONF plcLogConf, DEVINST dnDevInst, PRIORITY Priority,
00243     ULONG ulFlags)
00244 {
00245     TRACE("%p %p %lu %lx\n", plcLogConf, dnDevInst, Priority, ulFlags);
00246     return CM_Add_Empty_Log_Conf_Ex(plcLogConf, dnDevInst, Priority,
00247                                     ulFlags, NULL);
00248 }
00249 
00250 
00251 /***********************************************************************
00252  * CM_Add_Empty_Log_Conf_Ex [SETUPAPI.@]
00253  */
00254 CONFIGRET WINAPI CM_Add_Empty_Log_Conf_Ex(
00255     PLOG_CONF plcLogConf, DEVINST dnDevInst, PRIORITY Priority,
00256     ULONG ulFlags, HMACHINE hMachine)
00257 {
00258     RPC_BINDING_HANDLE BindingHandle = NULL;
00259     HSTRING_TABLE StringTable = NULL;
00260     ULONG ulLogConfTag = 0;
00261     LPWSTR lpDevInst;
00262     PLOG_CONF_INFO pLogConfInfo;
00263     CONFIGRET ret = CR_SUCCESS;
00264 
00265     FIXME("%p %p %lu %lx %p\n",
00266           plcLogConf, dnDevInst, Priority, ulFlags, hMachine);
00267 
00268     if (!pSetupIsUserAdmin())
00269         return CR_ACCESS_DENIED;
00270 
00271     if (plcLogConf == NULL)
00272         return CR_INVALID_POINTER;
00273 
00274     if (dnDevInst == 0)
00275         return CR_INVALID_DEVINST;
00276 
00277     if (Priority > 0xFFFF)
00278         return CR_INVALID_PRIORITY;
00279 
00280     if (ulFlags & ~(LOG_CONF_BITS | PRIORITY_BIT))
00281         return CR_INVALID_FLAG;
00282 
00283     if (hMachine != NULL)
00284     {
00285         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
00286         if (BindingHandle == NULL)
00287             return CR_FAILURE;
00288 
00289         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
00290         if (StringTable == 0)
00291             return CR_FAILURE;
00292     }
00293     else
00294     {
00295         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
00296             return CR_FAILURE;
00297     }
00298 
00299     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
00300     if (lpDevInst == NULL)
00301         return CR_INVALID_DEVNODE;
00302 
00303     RpcTryExcept
00304     {
00305         ret = PNP_AddEmptyLogConf(BindingHandle, lpDevInst, Priority,
00306                                   &ulLogConfTag, ulFlags);
00307     }
00308     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
00309     {
00310         ret = RpcStatusToCmStatus(RpcExceptionCode());
00311     }
00312     RpcEndExcept;
00313 
00314     if (ret == CR_SUCCESS)
00315     {
00316         pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
00317         if (pLogConfInfo == NULL)
00318         {
00319             ret = CR_OUT_OF_MEMORY;
00320         }
00321         else
00322         {
00323             pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
00324             pLogConfInfo->dnDevInst = dnDevInst;
00325             pLogConfInfo->ulFlags = ulFlags;
00326             pLogConfInfo->ulTag = ulLogConfTag;
00327 
00328             *plcLogConf = (LOG_CONF)pLogConfInfo;
00329 
00330             ret = CR_SUCCESS;
00331         }
00332     }
00333 
00334     return ret;
00335 }
00336 
00337 
00338 /***********************************************************************
00339  * CM_Add_IDA [SETUPAPI.@]
00340  */
00341 CONFIGRET WINAPI CM_Add_IDA(
00342     DEVINST dnDevInst, PSTR pszID, ULONG ulFlags)
00343 {
00344     TRACE("%p %s %lx\n", dnDevInst, pszID, ulFlags);
00345     return CM_Add_ID_ExA(dnDevInst, pszID, ulFlags, NULL);
00346 }
00347 
00348 
00349 /***********************************************************************
00350  * CM_Add_IDW [SETUPAPI.@]
00351  */
00352 CONFIGRET WINAPI CM_Add_IDW(
00353     DEVINST dnDevInst, PWSTR pszID, ULONG ulFlags)
00354 {
00355     TRACE("%p %s %lx\n", dnDevInst, debugstr_w(pszID), ulFlags);
00356     return CM_Add_ID_ExW(dnDevInst, pszID, ulFlags, NULL);
00357 }
00358 
00359 
00360 /***********************************************************************
00361  * CM_Add_ID_ExA [SETUPAPI.@]
00362  */
00363 CONFIGRET WINAPI CM_Add_ID_ExA(
00364     DEVINST dnDevInst, PSTR pszID, ULONG ulFlags, HMACHINE hMachine)
00365 {
00366     PWSTR pszIDW;
00367     CONFIGRET ret;
00368 
00369     TRACE("%p %s %lx %p\n", dnDevInst, pszID, ulFlags, hMachine);
00370 
00371     if (pSetupCaptureAndConvertAnsiArg(pszID, &pszIDW))
00372         return CR_INVALID_DATA;
00373 
00374     ret = CM_Add_ID_ExW(dnDevInst, pszIDW, ulFlags, hMachine);
00375 
00376     MyFree(pszIDW);
00377 
00378     return ret;
00379 }
00380 
00381 
00382 /***********************************************************************
00383  * CM_Add_ID_ExW [SETUPAPI.@]
00384  */
00385 CONFIGRET WINAPI CM_Add_ID_ExW(
00386     DEVINST dnDevInst, PWSTR pszID, ULONG ulFlags, HMACHINE hMachine)
00387 {
00388     RPC_BINDING_HANDLE BindingHandle = NULL;
00389     HSTRING_TABLE StringTable = NULL;
00390     LPWSTR lpDevInst;
00391     CONFIGRET ret;
00392 
00393     TRACE("%p %s %lx %p\n", dnDevInst, debugstr_w(pszID), ulFlags, hMachine);
00394 
00395     if (!pSetupIsUserAdmin())
00396         return CR_ACCESS_DENIED;
00397 
00398     if (dnDevInst == 0)
00399         return CR_INVALID_DEVINST;
00400 
00401     if (pszID == NULL)
00402         return CR_INVALID_POINTER;
00403 
00404     if (ulFlags & ~CM_ADD_ID_BITS)
00405         return CR_INVALID_FLAG;
00406 
00407     if (hMachine != NULL)
00408     {
00409         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
00410         if (BindingHandle == NULL)
00411             return CR_FAILURE;
00412 
00413         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
00414         if (StringTable == 0)
00415             return CR_FAILURE;
00416     }
00417     else
00418     {
00419         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
00420             return CR_FAILURE;
00421     }
00422 
00423     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
00424     if (lpDevInst == NULL)
00425         return CR_INVALID_DEVNODE;
00426 
00427     RpcTryExcept
00428     {
00429         ret = PNP_AddID(BindingHandle,
00430                         lpDevInst,
00431                         pszID,
00432                         ulFlags);
00433     }
00434     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
00435     {
00436         ret = RpcStatusToCmStatus(RpcExceptionCode());
00437     }
00438     RpcEndExcept;
00439 
00440     return ret;
00441 }
00442 
00443 
00444 /***********************************************************************
00445  * CM_Add_Res_Des [SETUPAPI.@]
00446  */
00447 CONFIGRET WINAPI CM_Add_Res_Des(
00448     PRES_DES prdResDes, LOG_CONF lcLogConf, RESOURCEID ResourceID,
00449     PCVOID ResourceData, ULONG ResourceLen, ULONG ulFlags)
00450 {
00451     TRACE("%p %p %lu %p %lu %lx\n", prdResDes, lcLogConf, ResourceID,
00452           ResourceData, ResourceLen, ulFlags);
00453     return CM_Add_Res_Des_Ex(prdResDes, lcLogConf, ResourceID, ResourceData,
00454                              ResourceLen, ulFlags, NULL);
00455 }
00456 
00457 
00458 /***********************************************************************
00459  * CM_Add_Res_Des_Ex [SETUPAPI.@]
00460  */
00461 CONFIGRET WINAPI CM_Add_Res_Des_Ex(
00462     PRES_DES prdResDes, LOG_CONF lcLogConf, RESOURCEID ResourceID,
00463     PCVOID ResourceData, ULONG ResourceLen, ULONG ulFlags, HMACHINE hMachine)
00464 {
00465     FIXME("%p %p %lu %p %lu %lx %p\n", prdResDes, lcLogConf, ResourceID,
00466           ResourceData, ResourceLen, ulFlags, hMachine);
00467 
00468     return CR_CALL_NOT_IMPLEMENTED;
00469 }
00470 
00471 
00472 /***********************************************************************
00473  * CM_Connect_MachineA [SETUPAPI.@]
00474  */
00475 CONFIGRET WINAPI CM_Connect_MachineA(
00476     PCSTR UNCServerName, PHMACHINE phMachine)
00477 {
00478     PWSTR pServerNameW;
00479     CONFIGRET ret;
00480 
00481     TRACE("%s %p\n", UNCServerName, phMachine);
00482 
00483     if (UNCServerName == NULL || *UNCServerName == 0)
00484         return CM_Connect_MachineW(NULL, phMachine);
00485 
00486     if (pSetupCaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))
00487         return CR_INVALID_DATA;
00488 
00489     ret = CM_Connect_MachineW(pServerNameW, phMachine);
00490 
00491     MyFree(pServerNameW);
00492 
00493     return ret;
00494 }
00495 
00496 
00497 /***********************************************************************
00498  * CM_Connect_MachineW [SETUPAPI.@]
00499  */
00500 CONFIGRET WINAPI CM_Connect_MachineW(
00501     PCWSTR UNCServerName, PHMACHINE phMachine)
00502 {
00503     PMACHINE_INFO pMachine;
00504 
00505     TRACE("%s %p\n", debugstr_w(UNCServerName), phMachine);
00506 
00507     if (phMachine == NULL)
00508         return CR_INVALID_POINTER;
00509 
00510     *phMachine = NULL;
00511 
00512     pMachine = HeapAlloc(GetProcessHeap(), 0, sizeof(MACHINE_INFO));
00513     if (pMachine == NULL)
00514         return CR_OUT_OF_MEMORY;
00515 
00516     if (UNCServerName == NULL || *UNCServerName == 0)
00517     {
00518         pMachine->bLocal = TRUE;
00519 
00520         /* FIXME: store the computers name in pMachine->szMachineName */
00521 
00522         if (!PnpGetLocalHandles(&pMachine->BindingHandle,
00523                                 &pMachine->StringTable))
00524         {
00525             HeapFree(GetProcessHeap(), 0, pMachine);
00526             return CR_FAILURE;
00527         }
00528     }
00529     else
00530     {
00531         pMachine->bLocal = FALSE;
00532         if (wcslen(UNCServerName) >= SP_MAX_MACHINENAME_LENGTH - 1)
00533         {
00534             HeapFree(GetProcessHeap(), 0, pMachine);
00535             return CR_INVALID_MACHINENAME;
00536         }
00537         lstrcpyW(pMachine->szMachineName, UNCServerName);
00538 
00539         pMachine->StringTable = pSetupStringTableInitialize();
00540         if (pMachine->StringTable == NULL)
00541         {
00542             HeapFree(GetProcessHeap(), 0, pMachine);
00543             return CR_FAILURE;
00544         }
00545 
00546         pSetupStringTableAddString(pMachine->StringTable, L"PLT", 1);
00547 
00548         if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))
00549         {
00550             pSetupStringTableDestroy(pMachine->StringTable);
00551             HeapFree(GetProcessHeap(), 0, pMachine);
00552             return CR_INVALID_MACHINENAME;
00553         }
00554     }
00555 
00556     phMachine = (PHMACHINE)pMachine;
00557 
00558     return CR_SUCCESS;
00559 }
00560 
00561 
00562 /***********************************************************************
00563  * CM_Create_DevNodeA [SETUPAPI.@]
00564  */
00565 CONFIGRET WINAPI CM_Create_DevNodeA(
00566     PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, DEVINST dnParent,
00567     ULONG ulFlags)
00568 {
00569     TRACE("%p %s %p %lx\n",
00570           pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags);
00571     return CM_Create_DevNode_ExA(pdnDevInst, pDeviceID, dnParent,
00572                                  ulFlags, NULL);
00573 }
00574 
00575 
00576 /***********************************************************************
00577  * CM_Create_DevNodeW [SETUPAPI.@]
00578  */
00579 CONFIGRET WINAPI CM_Create_DevNodeW(
00580     PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, DEVINST dnParent,
00581     ULONG ulFlags)
00582 {
00583     TRACE("%p %s %p %lx\n",
00584           pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags);
00585     return CM_Create_DevNode_ExW(pdnDevInst, pDeviceID, dnParent,
00586                                  ulFlags, NULL);
00587 }
00588 
00589 
00590 /***********************************************************************
00591  * CM_Create_DevNode_ExA [SETUPAPI.@]
00592  */
00593 CONFIGRET WINAPI CM_Create_DevNode_ExA(
00594     PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, DEVINST dnParent,
00595     ULONG ulFlags, HANDLE hMachine)
00596 {
00597     DEVINSTID_W pDeviceIDW;
00598     CONFIGRET ret;
00599 
00600     TRACE("%p %s %p %lx %p\n",
00601           pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags, hMachine);
00602 
00603     if (pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIDW))
00604         return CR_INVALID_DATA;
00605 
00606     ret = CM_Create_DevNode_ExW(pdnDevInst, pDeviceIDW, dnParent, ulFlags,
00607                                 hMachine);
00608 
00609     MyFree(pDeviceIDW);
00610 
00611     return ret;
00612 }
00613 
00614 
00615 /***********************************************************************
00616  * CM_Create_DevNode_ExW [SETUPAPI.@]
00617  */
00618 CONFIGRET WINAPI CM_Create_DevNode_ExW(
00619     PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, DEVINST dnParent,
00620     ULONG ulFlags, HANDLE hMachine)
00621 {
00622     RPC_BINDING_HANDLE BindingHandle = NULL;
00623     HSTRING_TABLE StringTable = NULL;
00624     LPWSTR lpParentDevInst;
00625     CONFIGRET ret = CR_SUCCESS;
00626     WCHAR szLocalDeviceID[MAX_DEVICE_ID_LEN];
00627 
00628     TRACE("%p %s %p %lx %p\n",
00629           pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags, hMachine);
00630 
00631     if (!pSetupIsUserAdmin())
00632         return CR_ACCESS_DENIED;
00633 
00634     if (pdnDevInst == NULL)
00635         return CR_INVALID_POINTER;
00636 
00637     if (pDeviceID == NULL || wcslen(pDeviceID) == 0 || wcslen(pDeviceID) >= MAX_DEVICE_ID_LEN)
00638         return CR_INVALID_DEVICE_ID;
00639 
00640     if (dnParent == 0)
00641         return CR_INVALID_DEVNODE;
00642 
00643     if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
00644         return CR_INVALID_FLAG;
00645 
00646     if (hMachine != NULL)
00647     {
00648         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
00649         if (BindingHandle == NULL)
00650             return CR_FAILURE;
00651 
00652         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
00653         if (StringTable == 0)
00654             return CR_FAILURE;
00655     }
00656     else
00657     {
00658         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
00659             return CR_FAILURE;
00660     }
00661 
00662     lpParentDevInst = pSetupStringTableStringFromId(StringTable, dnParent);
00663     if (lpParentDevInst == NULL)
00664         return CR_INVALID_DEVNODE;
00665 
00666     wcscpy(szLocalDeviceID, pDeviceID);
00667 
00668     RpcTryExcept
00669     {
00670         ret = PNP_CreateDevInst(BindingHandle,
00671                                 szLocalDeviceID,
00672                                 lpParentDevInst,
00673                                 MAX_DEVICE_ID_LEN,
00674                                 ulFlags);
00675     }
00676     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
00677     {
00678         ret = RpcStatusToCmStatus(RpcExceptionCode());
00679     }
00680     RpcEndExcept;
00681 
00682     if (ret == CR_SUCCESS)
00683     {
00684         *pdnDevInst = pSetupStringTableAddString(StringTable, pDeviceID, 1);
00685         if (*pdnDevInst == 0)
00686             ret = CR_NO_SUCH_DEVNODE;
00687     }
00688 
00689     return ret;
00690 }
00691 
00692 
00693 /***********************************************************************
00694  * CM_Delete_Class_Key [SETUPAPI.@]
00695  */
00696 CONFIGRET WINAPI CM_Delete_Class_Key(
00697     LPGUID ClassGuid, ULONG ulFlags)
00698 {
00699     TRACE("%p %lx\n", ClassGuid, ulFlags);
00700     return CM_Delete_Class_Key_Ex(ClassGuid, ulFlags, NULL);
00701 }
00702 
00703 
00704 /***********************************************************************
00705  * CM_Delete_Class_Key_Ex [SETUPAPI.@]
00706  */
00707 CONFIGRET WINAPI CM_Delete_Class_Key_Ex(
00708     LPGUID ClassGuid, ULONG ulFlags, HANDLE hMachine)
00709 {
00710     WCHAR szGuidString[MAX_GUID_STRING_LEN];
00711     RPC_BINDING_HANDLE BindingHandle = NULL;
00712     CONFIGRET ret;
00713 
00714     TRACE("%p %lx %lx\n", ClassGuid, ulFlags, hMachine);
00715 
00716     if (ClassGuid == NULL)
00717         return CR_INVALID_POINTER;
00718 
00719     if (ulFlags & ~CM_DELETE_CLASS_BITS)
00720         return CR_INVALID_FLAG;
00721 
00722     if (!GuidToString(ClassGuid, szGuidString))
00723         return CR_INVALID_DATA;
00724 
00725     if (hMachine != NULL)
00726     {
00727         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
00728         if (BindingHandle == NULL)
00729             return CR_FAILURE;
00730     }
00731     else
00732     {
00733         if (!PnpGetLocalHandles(&BindingHandle, NULL))
00734             return CR_FAILURE;
00735     }
00736 
00737     RpcTryExcept
00738     {
00739         ret = PNP_DeleteClassKey(BindingHandle,
00740                                  szGuidString,
00741                                  ulFlags);
00742     }
00743     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
00744     {
00745         ret = RpcStatusToCmStatus(RpcExceptionCode());
00746     }
00747     RpcEndExcept;
00748 
00749     return ret;
00750 }
00751 
00752 
00753 /***********************************************************************
00754  * CM_Delete_DevNode_Key [SETUPAPI.@]
00755  */
00756 CONFIGRET WINAPI CM_Delete_DevNode_Key(
00757     DEVNODE dnDevNode, ULONG ulHardwareProfile, ULONG ulFlags)
00758 {
00759     TRACE("%p %lu %lx\n", dnDevNode, ulHardwareProfile, ulFlags);
00760     return CM_Delete_DevNode_Key_Ex(dnDevNode, ulHardwareProfile, ulFlags,
00761                                     NULL);
00762 }
00763 
00764 
00765 /***********************************************************************
00766  * CM_Delete_DevNode_Key_Ex [SETUPAPI.@]
00767  */
00768 CONFIGRET WINAPI CM_Delete_DevNode_Key_Ex(
00769     DEVNODE dnDevNode, ULONG ulHardwareProfile, ULONG ulFlags,
00770     HANDLE hMachine)
00771 {
00772     FIXME("%p %lu %lx %p\n",
00773           dnDevNode, ulHardwareProfile, ulFlags, hMachine);
00774 
00775     return CR_CALL_NOT_IMPLEMENTED;
00776 }
00777 
00778 
00779 /***********************************************************************
00780  * CM_Disable_DevNode [SETUPAPI.@]
00781  */
00782 CONFIGRET WINAPI CM_Disable_DevNode(
00783     DEVINST dnDevInst, ULONG ulFlags)
00784 {
00785     TRACE("%p %lx\n", dnDevInst, ulFlags);
00786     return CM_Disable_DevNode_Ex(dnDevInst, ulFlags, NULL);
00787 }
00788 
00789 
00790 /***********************************************************************
00791  * CM_Disable_DevNode_Ex [SETUPAPI.@]
00792  */
00793 CONFIGRET WINAPI CM_Disable_DevNode_Ex(
00794     DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
00795 {
00796     RPC_BINDING_HANDLE BindingHandle = NULL;
00797     HSTRING_TABLE StringTable = NULL;
00798     LPWSTR lpDevInst;
00799     CONFIGRET ret;
00800 
00801     FIXME("%p %lx %p\n", dnDevInst, ulFlags, hMachine);
00802 
00803     if (!pSetupIsUserAdmin())
00804         return CR_ACCESS_DENIED;
00805 
00806     if (dnDevInst == 0)
00807         return CR_INVALID_DEVINST;
00808 
00809     if (ulFlags != 0)
00810         return CR_INVALID_FLAG;
00811 
00812     if (hMachine != NULL)
00813     {
00814         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
00815         if (BindingHandle == NULL)
00816             return CR_FAILURE;
00817 
00818         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
00819         if (StringTable == 0)
00820             return CR_FAILURE;
00821     }
00822     else
00823     {
00824         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
00825             return CR_FAILURE;
00826     }
00827 
00828     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
00829     if (lpDevInst == NULL)
00830         return CR_INVALID_DEVNODE;
00831 
00832     RpcTryExcept
00833     {
00834         ret = PNP_DeviceInstanceAction(BindingHandle,
00835                                        PNP_DEVINST_DISABLE,
00836                                        ulFlags,
00837                                        lpDevInst,
00838                                        NULL);
00839     }
00840     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
00841     {
00842         ret = RpcStatusToCmStatus(RpcExceptionCode());
00843     }
00844     RpcEndExcept;
00845 
00846     return ret;
00847 }
00848 
00849 
00850 /***********************************************************************
00851  * CM_Disconnect_Machine [SETUPAPI.@]
00852  */
00853 CONFIGRET WINAPI CM_Disconnect_Machine(HMACHINE hMachine)
00854 {
00855     PMACHINE_INFO pMachine;
00856 
00857     TRACE("%lx\n", hMachine);
00858 
00859     pMachine = (PMACHINE_INFO)hMachine;
00860     if (pMachine == NULL)
00861         return CR_SUCCESS;
00862 
00863     if (pMachine->bLocal == FALSE)
00864     {
00865         if (pMachine->StringTable != NULL)
00866             pSetupStringTableDestroy(pMachine->StringTable);
00867 
00868         if (!PnpUnbindRpc(pMachine->BindingHandle))
00869             return CR_ACCESS_DENIED;
00870     }
00871 
00872     HeapFree(GetProcessHeap(), 0, pMachine);
00873 
00874     return CR_SUCCESS;
00875 }
00876 
00877 
00878 /***********************************************************************
00879  * CM_Enable_DevNode [SETUPAPI.@]
00880  */
00881 CONFIGRET WINAPI CM_Enable_DevNode(
00882     DEVINST dnDevInst, ULONG ulFlags)
00883 {
00884     TRACE("%p %lx\n", dnDevInst, ulFlags);
00885     return CM_Enable_DevNode_Ex(dnDevInst, ulFlags, NULL);
00886 }
00887 
00888 
00889 /***********************************************************************
00890  * CM_Enable_DevNode_Ex [SETUPAPI.@]
00891  */
00892 CONFIGRET WINAPI CM_Enable_DevNode_Ex(
00893     DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
00894 {
00895     RPC_BINDING_HANDLE BindingHandle = NULL;
00896     HSTRING_TABLE StringTable = NULL;
00897     LPWSTR lpDevInst;
00898     CONFIGRET ret;
00899 
00900     TRACE("%p %lx %p\n", dnDevInst, ulFlags, hMachine);
00901 
00902     if (!pSetupIsUserAdmin())
00903         return CR_ACCESS_DENIED;
00904 
00905     if (dnDevInst == 0)
00906         return CR_INVALID_DEVINST;
00907 
00908     if (ulFlags != 0)
00909         return CR_INVALID_FLAG;
00910 
00911     if (hMachine != NULL)
00912     {
00913         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
00914         if (BindingHandle == NULL)
00915             return CR_FAILURE;
00916 
00917         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
00918         if (StringTable == 0)
00919             return CR_FAILURE;
00920     }
00921     else
00922     {
00923         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
00924             return CR_FAILURE;
00925     }
00926 
00927     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
00928     if (lpDevInst == NULL)
00929         return CR_INVALID_DEVNODE;
00930 
00931     RpcTryExcept
00932     {
00933         ret = PNP_DeviceInstanceAction(BindingHandle,
00934                                        PNP_DEVINST_ENABLE,
00935                                        ulFlags,
00936                                        lpDevInst,
00937                                        NULL);
00938     }
00939     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
00940     {
00941         ret = RpcStatusToCmStatus(RpcExceptionCode());
00942     }
00943     RpcEndExcept;
00944 
00945     return ret;
00946 }
00947 
00948 
00949 /***********************************************************************
00950  * CM_Enumerate_Classes [SETUPAPI.@]
00951  */
00952 CONFIGRET WINAPI CM_Enumerate_Classes(
00953     ULONG ulClassIndex, LPGUID ClassGuid, ULONG ulFlags)
00954 {
00955     TRACE("%lx %p %lx\n", ulClassIndex, ClassGuid, ulFlags);
00956     return CM_Enumerate_Classes_Ex(ulClassIndex, ClassGuid, ulFlags, NULL);
00957 }
00958 
00959 
00960 /***********************************************************************
00961  * CM_Enumerate_Classes_Ex [SETUPAPI.@]
00962  */
00963 CONFIGRET WINAPI CM_Enumerate_Classes_Ex(
00964     ULONG ulClassIndex, LPGUID ClassGuid, ULONG ulFlags, HMACHINE hMachine)
00965 {
00966     WCHAR szBuffer[MAX_GUID_STRING_LEN];
00967     RPC_BINDING_HANDLE BindingHandle = NULL;
00968     CONFIGRET ret = CR_SUCCESS;
00969     ULONG ulLength = MAX_GUID_STRING_LEN;
00970 
00971     TRACE("%lx %p %lx %p\n", ulClassIndex, ClassGuid, ulFlags, hMachine);
00972 
00973     if (ClassGuid == NULL)
00974         return CR_INVALID_POINTER;
00975 
00976     if (ulFlags != 0)
00977         return CR_INVALID_FLAG;
00978 
00979     if (hMachine != NULL)
00980     {
00981         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
00982         if (BindingHandle == NULL)
00983             return CR_FAILURE;
00984     }
00985     else
00986     {
00987         if (!PnpGetLocalHandles(&BindingHandle, NULL))
00988             return CR_FAILURE;
00989     }
00990 
00991     RpcTryExcept
00992     {
00993         ret = PNP_EnumerateSubKeys(BindingHandle,
00994                                    PNP_CLASS_SUBKEYS,
00995                                    ulClassIndex,
00996                                    szBuffer,
00997                                    MAX_GUID_STRING_LEN,
00998                                    &ulLength,
00999                                    ulFlags);
01000     }
01001     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
01002     {
01003         ret = RpcStatusToCmStatus(RpcExceptionCode());
01004     }
01005     RpcEndExcept;
01006 
01007     if (ret == CR_SUCCESS)
01008     {
01009         /* Remove the {} */
01010         szBuffer[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
01011 
01012         /* Convert the buffer to a GUID */
01013         if (UuidFromStringW(&szBuffer[1], ClassGuid) != RPC_S_OK)
01014             return CR_FAILURE;
01015     }
01016 
01017     return ret;
01018 }
01019 
01020 
01021 /***********************************************************************
01022  * CM_Enumerate_EnumeratorsA [SETUPAPI.@]
01023  */
01024 CONFIGRET WINAPI CM_Enumerate_EnumeratorsA(
01025     ULONG ulEnumIndex, PCHAR Buffer, PULONG pulLength, ULONG ulFlags)
01026 {
01027     TRACE("%lu %p %p %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags);
01028     return CM_Enumerate_Enumerators_ExA(ulEnumIndex, Buffer, pulLength,
01029                                         ulFlags, NULL);
01030 }
01031 
01032 
01033 /***********************************************************************
01034  * CM_Enumerate_EnumeratorsW [SETUPAPI.@]
01035  */
01036 CONFIGRET WINAPI CM_Enumerate_EnumeratorsW(
01037     ULONG ulEnumIndex, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags)
01038 {
01039     TRACE("%lu %p %p %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags);
01040     return CM_Enumerate_Enumerators_ExW(ulEnumIndex, Buffer, pulLength,
01041                                         ulFlags, NULL);
01042 }
01043 
01044 
01045 /***********************************************************************
01046  * CM_Enumerate_Enumerators_ExA [SETUPAPI.@]
01047  */
01048 CONFIGRET WINAPI CM_Enumerate_Enumerators_ExA(
01049     ULONG ulEnumIndex, PCHAR Buffer, PULONG pulLength, ULONG ulFlags,
01050     HMACHINE hMachine)
01051 {
01052     WCHAR szBuffer[MAX_DEVICE_ID_LEN];
01053     ULONG ulOrigLength;
01054     ULONG ulLength;
01055     CONFIGRET ret = CR_SUCCESS;
01056 
01057     TRACE("%lu %p %p %lx %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags,
01058           hMachine);
01059 
01060     if (Buffer == NULL || pulLength == NULL)
01061         return CR_INVALID_POINTER;
01062 
01063     if (ulFlags != 0)
01064         return CR_INVALID_FLAG;
01065 
01066     ulOrigLength = *pulLength;
01067     *pulLength = 0;
01068 
01069     ulLength = MAX_DEVICE_ID_LEN;
01070     ret = CM_Enumerate_Enumerators_ExW(ulEnumIndex, szBuffer, &ulLength,
01071                                        ulFlags, hMachine);
01072     if (ret == CR_SUCCESS)
01073     {
01074         if (WideCharToMultiByte(CP_ACP,
01075                                 0,
01076                                 szBuffer,
01077                                 ulLength,
01078                                 Buffer,
01079                                 ulOrigLength,
01080                                 NULL,
01081                                 NULL) == 0)
01082             ret = CR_FAILURE;
01083         else
01084             *pulLength = lstrlenA(Buffer) + 1;
01085     }
01086 
01087     return ret;
01088 }
01089 
01090 
01091 /***********************************************************************
01092  * CM_Enumerate_Enumerators_ExW [SETUPAPI.@]
01093  */
01094 CONFIGRET WINAPI CM_Enumerate_Enumerators_ExW(
01095     ULONG ulEnumIndex, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags,
01096     HMACHINE hMachine)
01097 {
01098     RPC_BINDING_HANDLE BindingHandle = NULL;
01099     CONFIGRET ret;
01100 
01101     TRACE("%lu %p %p %lx %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags,
01102           hMachine);
01103 
01104     if (Buffer == NULL || pulLength == NULL)
01105         return CR_INVALID_POINTER;
01106 
01107     if (ulFlags != 0)
01108         return CR_INVALID_FLAG;
01109 
01110     *Buffer = UNICODE_NULL;
01111 
01112     if (hMachine != NULL)
01113     {
01114         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
01115         if (BindingHandle == NULL)
01116             return CR_FAILURE;
01117     }
01118     else
01119     {
01120         if (!PnpGetLocalHandles(&BindingHandle, NULL))
01121             return CR_FAILURE;
01122     }
01123 
01124     RpcTryExcept
01125     {
01126         ret = PNP_EnumerateSubKeys(BindingHandle,
01127                                    PNP_ENUMERATOR_SUBKEYS,
01128                                    ulEnumIndex,
01129                                    Buffer,
01130                                    *pulLength,
01131                                    pulLength,
01132                                    ulFlags);
01133     }
01134     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
01135     {
01136         ret = RpcStatusToCmStatus(RpcExceptionCode());
01137     }
01138     RpcEndExcept;
01139 
01140     return ret;
01141 }
01142 
01143 
01144 /***********************************************************************
01145  * CM_Free_Log_Conf [SETUPAPI.@]
01146  */
01147 CONFIGRET WINAPI CM_Free_Log_Conf(
01148     LOG_CONF lcLogConfToBeFreed, ULONG ulFlags)
01149 {
01150     TRACE("%lx %lx\n", lcLogConfToBeFreed, ulFlags);
01151     return CM_Free_Log_Conf_Ex(lcLogConfToBeFreed, ulFlags, NULL);
01152 }
01153 
01154 
01155 /***********************************************************************
01156  * CM_Free_Log_Conf_Ex [SETUPAPI.@]
01157  */
01158 CONFIGRET WINAPI CM_Free_Log_Conf_Ex(
01159     LOG_CONF lcLogConfToBeFreed, ULONG ulFlags, HMACHINE hMachine)
01160 {
01161     RPC_BINDING_HANDLE BindingHandle = NULL;
01162     HSTRING_TABLE StringTable = NULL;
01163     LPWSTR lpDevInst;
01164     PLOG_CONF_INFO pLogConfInfo;
01165     CONFIGRET ret;
01166 
01167     TRACE("%lx %lx %lx\n", lcLogConfToBeFreed, ulFlags, hMachine);
01168 
01169     if (!pSetupIsUserAdmin())
01170         return CR_ACCESS_DENIED;
01171 
01172     pLogConfInfo = (PLOG_CONF_INFO)lcLogConfToBeFreed;
01173     if (pLogConfInfo == NULL || pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
01174         return CR_INVALID_LOG_CONF;
01175 
01176     if (ulFlags != 0)
01177         return CR_INVALID_FLAG;
01178 
01179     if (hMachine != NULL)
01180     {
01181         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
01182         if (BindingHandle == NULL)
01183             return CR_FAILURE;
01184 
01185         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
01186         if (StringTable == 0)
01187             return CR_FAILURE;
01188     }
01189     else
01190     {
01191         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
01192             return CR_FAILURE;
01193     }
01194 
01195     lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
01196     if (lpDevInst == NULL)
01197         return CR_INVALID_DEVNODE;
01198 
01199     RpcTryExcept
01200     {
01201         ret = PNP_FreeLogConf(BindingHandle, lpDevInst, pLogConfInfo->ulFlags,
01202                               pLogConfInfo->ulTag, 0);
01203     }
01204     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
01205     {
01206         ret = RpcStatusToCmStatus(RpcExceptionCode());
01207     }
01208     RpcEndExcept;
01209 
01210     return ret;
01211 }
01212 
01213 
01214 /***********************************************************************
01215  * CM_Free_Log_Conf_Handle [SETUPAPI.@]
01216  */
01217 CONFIGRET WINAPI CM_Free_Log_Conf_Handle(
01218     LOG_CONF lcLogConf)
01219 {
01220     PLOG_CONF_INFO pLogConfInfo;
01221 
01222     TRACE("%lx\n", lcLogConf);
01223 
01224     pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
01225     if (pLogConfInfo == NULL || pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
01226         return CR_INVALID_LOG_CONF;
01227 
01228     HeapFree(GetProcessHeap(), 0, pLogConfInfo);
01229 
01230     return CR_SUCCESS;
01231 }
01232 
01233 
01234 /***********************************************************************
01235  * CM_Free_Res_Des [SETUPAPI.@]
01236  */
01237 CONFIGRET WINAPI CM_Free_Res_Des(
01238    PRES_DES prdResDes, RES_DES rdResDes, ULONG ulFlags)
01239 {
01240     TRACE("%p %p %lx\n", prdResDes, rdResDes, ulFlags);
01241     return CM_Free_Res_Des_Ex(prdResDes, rdResDes, ulFlags, NULL);
01242 }
01243 
01244 
01245 /***********************************************************************
01246  * CM_Free_Res_Des_Ex [SETUPAPI.@]
01247  */
01248 CONFIGRET WINAPI CM_Free_Res_Des_Ex(
01249     PRES_DES prdResDes, RES_DES rdResDes, ULONG ulFlags,
01250     HMACHINE hMachine)
01251 {
01252     FIXME("%p %p %lx %lx\n", prdResDes, rdResDes, ulFlags, hMachine);
01253 
01254     return CR_CALL_NOT_IMPLEMENTED;
01255 }
01256 
01257 
01258 /***********************************************************************
01259  * CM_Free_Res_Des_Handle [SETUPAPI.@]
01260  */
01261 CONFIGRET WINAPI CM_Free_Res_Des_Handle(
01262     RES_DES rdResDes)
01263 {
01264     FIXME("%p\n", rdResDes);
01265 
01266     return CR_CALL_NOT_IMPLEMENTED;
01267 }
01268 
01269 
01270 /***********************************************************************
01271  * CM_Get_Child [SETUPAPI.@]
01272  */
01273 CONFIGRET WINAPI CM_Get_Child(
01274     PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
01275 {
01276     TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
01277     return CM_Get_Child_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
01278 }
01279 
01280 
01281 /***********************************************************************
01282  * CM_Get_Child_Ex [SETUPAPI.@]
01283  */
01284 CONFIGRET WINAPI CM_Get_Child_Ex(
01285     PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
01286 {
01287     WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
01288     RPC_BINDING_HANDLE BindingHandle = NULL;
01289     HSTRING_TABLE StringTable = NULL;
01290     LPWSTR lpDevInst;
01291     DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
01292     CONFIGRET ret;
01293 
01294     TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
01295 
01296     if (pdnDevInst == NULL)
01297         return CR_INVALID_POINTER;
01298 
01299     if (dnDevInst == 0)
01300         return CR_INVALID_DEVINST;
01301 
01302     if (ulFlags != 0)
01303         return CR_INVALID_FLAG;
01304 
01305     *pdnDevInst = -1;
01306 
01307     if (hMachine != NULL)
01308     {
01309         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
01310         if (BindingHandle == NULL)
01311             return CR_FAILURE;
01312 
01313         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
01314         if (StringTable == 0)
01315             return CR_FAILURE;
01316     }
01317     else
01318     {
01319         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
01320             return CR_FAILURE;
01321     }
01322 
01323     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
01324     if (lpDevInst == NULL)
01325         return CR_INVALID_DEVNODE;
01326 
01327     RpcTryExcept
01328     {
01329         ret = PNP_GetRelatedDeviceInstance(BindingHandle,
01330                                            PNP_GET_CHILD_DEVICE_INSTANCE,
01331                                            lpDevInst,
01332                                            szRelatedDevInst,
01333                                            &dwLength,
01334                                            0);
01335     }
01336     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
01337     {
01338         ret = RpcStatusToCmStatus(RpcExceptionCode());
01339     }
01340     RpcEndExcept;
01341 
01342     if (ret != CR_SUCCESS)
01343         return ret;
01344 
01345     TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
01346 
01347     dwIndex = pSetupStringTableAddString(StringTable, szRelatedDevInst, 1);
01348     if (dwIndex == -1)
01349         return CR_FAILURE;
01350 
01351     *pdnDevInst = dwIndex;
01352 
01353     return CR_SUCCESS;
01354 }
01355 
01356 
01357 /***********************************************************************
01358  * CM_Get_Class_Key_NameA [SETUPAPI.@]
01359  */
01360 CONFIGRET WINAPI CM_Get_Class_Key_NameA(
01361     LPGUID ClassGuid, LPSTR pszKeyName, PULONG pulLength, ULONG ulFlags)
01362 {
01363     TRACE("%p %p %p %lx\n",
01364           ClassGuid, pszKeyName, pulLength, ulFlags);
01365     return CM_Get_Class_Key_Name_ExA(ClassGuid, pszKeyName, pulLength,
01366                                      ulFlags, NULL);
01367 }
01368 
01369 
01370 /***********************************************************************
01371  * CM_Get_Class_Key_NameW [SETUPAPI.@]
01372  */
01373 CONFIGRET WINAPI CM_Get_Class_Key_NameW(
01374     LPGUID ClassGuid, LPWSTR pszKeyName, PULONG pulLength, ULONG ulFlags)
01375 {
01376     TRACE("%p %p %p %lx\n",
01377           ClassGuid, pszKeyName, pulLength, ulFlags);
01378     return CM_Get_Class_Key_Name_ExW(ClassGuid, pszKeyName, pulLength,
01379                                      ulFlags, NULL);
01380 }
01381 
01382 
01383 /***********************************************************************
01384  * CM_Get_Class_Key_Name_ExA [SETUPAPI.@]
01385  */
01386 CONFIGRET WINAPI CM_Get_Class_Key_Name_ExA(
01387     LPGUID ClassGuid, LPSTR pszKeyName, PULONG pulLength, ULONG ulFlags,
01388     HMACHINE hMachine)
01389 {
01390     WCHAR szBuffer[MAX_GUID_STRING_LEN];
01391     CONFIGRET ret = CR_SUCCESS;
01392     ULONG ulLength;
01393     ULONG ulOrigLength;
01394 
01395     TRACE("%p %p %p %lx %lx\n",
01396           ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
01397 
01398     if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
01399         return CR_INVALID_POINTER;
01400 
01401     ulOrigLength = *pulLength;
01402     *pulLength = 0;
01403 
01404     ulLength = MAX_GUID_STRING_LEN;
01405     ret = CM_Get_Class_Key_Name_ExW(ClassGuid, szBuffer, &ulLength,
01406                                     ulFlags, hMachine);
01407     if (ret == CR_SUCCESS)
01408     {
01409         if (WideCharToMultiByte(CP_ACP,
01410                                 0,
01411                                 szBuffer,
01412                                 ulLength,
01413                                 pszKeyName,
01414                                 ulOrigLength,
01415                                 NULL,
01416                                 NULL) == 0)
01417             ret = CR_FAILURE;
01418         else
01419             *pulLength = lstrlenA(pszKeyName) + 1;
01420     }
01421 
01422     return CR_SUCCESS;
01423 }
01424 
01425 
01426 /***********************************************************************
01427  * CM_Get_Class_Key_Name_ExW [SETUPAPI.@]
01428  */
01429 CONFIGRET WINAPI CM_Get_Class_Key_Name_ExW(
01430     LPGUID ClassGuid, LPWSTR pszKeyName, PULONG pulLength, ULONG ulFlags,
01431     HMACHINE hMachine)
01432 {
01433     TRACE("%p %p %p %lx %lx\n",
01434           ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
01435 
01436     if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
01437         return CR_INVALID_POINTER;
01438 
01439     if (ulFlags != 0)
01440         return CR_INVALID_FLAG;
01441 
01442     if (*pulLength < MAX_GUID_STRING_LEN)
01443     {
01444         *pulLength = 0;
01445         return CR_BUFFER_SMALL;
01446     }
01447 
01448     if (!GuidToString(ClassGuid, pszKeyName))
01449         return CR_INVALID_DATA;
01450 
01451     *pulLength = MAX_GUID_STRING_LEN;
01452 
01453     return CR_SUCCESS;
01454 }
01455 
01456 
01457 /***********************************************************************
01458  * CM_Get_Class_NameA [SETUPAPI.@]
01459  */
01460 CONFIGRET WINAPI CM_Get_Class_NameA(
01461     LPGUID ClassGuid, PCHAR Buffer, PULONG pulLength, ULONG ulFlags)
01462 {
01463     TRACE("%p %p %p %lx\n", ClassGuid, Buffer, pulLength, ulFlags);
01464     return CM_Get_Class_Name_ExA(ClassGuid, Buffer, pulLength, ulFlags,
01465                                  NULL);
01466 }
01467 
01468 
01469 /***********************************************************************
01470  * CM_Get_Class_NameW [SETUPAPI.@]
01471  */
01472 CONFIGRET WINAPI CM_Get_Class_NameW(
01473     LPGUID ClassGuid, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags)
01474 {
01475     TRACE("%p %p %p %lx\n", ClassGuid, Buffer, pulLength, ulFlags);
01476     return CM_Get_Class_Name_ExW(ClassGuid, Buffer, pulLength, ulFlags,
01477                                  NULL);
01478 }
01479 
01480 
01481 /***********************************************************************
01482  * CM_Get_Class_Name_ExA [SETUPAPI.@]
01483  */
01484 CONFIGRET WINAPI CM_Get_Class_Name_ExA(
01485     LPGUID ClassGuid, PCHAR Buffer, PULONG pulLength, ULONG ulFlags,
01486     HMACHINE hMachine)
01487 {
01488     WCHAR szBuffer[MAX_CLASS_NAME_LEN];
01489     CONFIGRET ret = CR_SUCCESS;
01490     ULONG ulLength;
01491     ULONG ulOrigLength;
01492 
01493     TRACE("%p %p %p %lx %lx\n",
01494           ClassGuid, Buffer, pulLength, ulFlags, hMachine);
01495 
01496     if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
01497         return CR_INVALID_POINTER;
01498 
01499     ulOrigLength = *pulLength;
01500     *pulLength = 0;
01501 
01502     ulLength = MAX_CLASS_NAME_LEN;
01503     ret = CM_Get_Class_Name_ExW(ClassGuid, szBuffer, &ulLength,
01504                                 ulFlags, hMachine);
01505     if (ret == CR_SUCCESS)
01506     {
01507         if (WideCharToMultiByte(CP_ACP,
01508                                 0,
01509                                 szBuffer,
01510                                 ulLength,
01511                                 Buffer,
01512                                 ulOrigLength,
01513                                 NULL,
01514                                 NULL) == 0)
01515             ret = CR_FAILURE;
01516         else
01517             *pulLength = lstrlenA(Buffer) + 1;
01518     }
01519 
01520     return ret;
01521 }
01522 
01523 
01524 /***********************************************************************
01525  * CM_Get_Class_Name_ExW [SETUPAPI.@]
01526  */
01527 CONFIGRET WINAPI
01528 CM_Get_Class_Name_ExW(
01529     LPGUID ClassGuid, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags,
01530     HMACHINE hMachine)
01531 {
01532     WCHAR szGuidString[MAX_GUID_STRING_LEN];
01533     RPC_BINDING_HANDLE BindingHandle = NULL;
01534     CONFIGRET ret;
01535 
01536     TRACE("%p %p %p %lx %lx\n",
01537           ClassGuid, Buffer, pulLength, ulFlags, hMachine);
01538 
01539     if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
01540         return CR_INVALID_POINTER;
01541 
01542     if (ulFlags != 0)
01543         return CR_INVALID_FLAG;
01544 
01545     if (!GuidToString(ClassGuid, szGuidString))
01546         return CR_INVALID_DATA;
01547 
01548     TRACE("Guid %s\n", debugstr_w(szGuidString));
01549 
01550     if (hMachine != NULL)
01551     {
01552         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
01553         if (BindingHandle == NULL)
01554             return CR_FAILURE;
01555     }
01556     else
01557     {
01558         if (!PnpGetLocalHandles(&BindingHandle, NULL))
01559             return CR_FAILURE;
01560     }
01561 
01562     RpcTryExcept
01563     {
01564         ret = PNP_GetClassName(BindingHandle,
01565                                szGuidString,
01566                                Buffer,
01567                                pulLength,
01568                                ulFlags);
01569     }
01570     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
01571     {
01572         ret = RpcStatusToCmStatus(RpcExceptionCode());
01573     }
01574     RpcEndExcept;
01575 
01576     return ret;
01577 }
01578 
01579 
01580 /***********************************************************************
01581  * CM_Get_Class_Registry_PropertyA [SETUPAPI.@]
01582  */
01583 CONFIGRET WINAPI CM_Get_Class_Registry_PropertyA(
01584     LPGUID ClassGuid, ULONG ulProperty, PULONG pulRegDataType,
01585     PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
01586 {
01587     FIXME("%p %lu %p %p %p %lx %lx\n",
01588           ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
01589           ulFlags, hMachine);
01590     return CR_CALL_NOT_IMPLEMENTED;
01591 }
01592 
01593 
01594 /***********************************************************************
01595  * CM_Get_Class_Registry_PropertyW [SETUPAPI.@]
01596  */
01597 CONFIGRET WINAPI CM_Get_Class_Registry_PropertyW(
01598     LPGUID ClassGuid, ULONG ulProperty, PULONG pulRegDataType,
01599     PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
01600 {
01601     RPC_BINDING_HANDLE BindingHandle = NULL;
01602     WCHAR szGuidString[PNP_MAX_GUID_STRING_LEN + 1];
01603     ULONG ulType = 0;
01604     ULONG ulTransferLength = 0;
01605     CONFIGRET ret;
01606 
01607     TRACE("%p %lu %p %p %p %lx %lx\n",
01608           ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
01609           ulFlags, hMachine);
01610 
01611     if (ClassGuid == NULL || pulLength == NULL)
01612         return CR_INVALID_POINTER;
01613 
01614     if (ulFlags != 0)
01615         return CR_INVALID_FLAG;
01616 
01617     if (pSetupStringFromGuid(ClassGuid,
01618                              szGuidString,
01619                              PNP_MAX_GUID_STRING_LEN) != 0)
01620         return CR_INVALID_DATA;
01621 
01622     if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
01623         return CR_INVALID_PROPERTY;
01624 
01625     if (hMachine != NULL)
01626     {
01627         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
01628         if (BindingHandle == NULL)
01629             return CR_FAILURE;
01630     }
01631     else
01632     {
01633         if (!PnpGetLocalHandles(&BindingHandle, NULL))
01634             return CR_FAILURE;
01635     }
01636 
01637     ulTransferLength = *pulLength;
01638 
01639     RpcTryExcept
01640     {
01641         ret = PNP_GetClassRegProp(BindingHandle,
01642                                   szGuidString,
01643                                   ulProperty,
01644                                   &ulType,
01645                                   Buffer,
01646                                   &ulTransferLength,
01647                                   pulLength,
01648                                   ulFlags);
01649     }
01650     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
01651     {
01652         ret = RpcStatusToCmStatus(RpcExceptionCode());
01653     }
01654     RpcEndExcept;
01655 
01656     if (ret == CR_SUCCESS)
01657     {
01658         if (pulRegDataType != NULL)
01659             *pulRegDataType = ulType;
01660     }
01661 
01662     return ret;
01663 }
01664 
01665 
01666 /***********************************************************************
01667  * CM_Get_Depth [SETUPAPI.@]
01668  */
01669 CONFIGRET WINAPI CM_Get_Depth(
01670     PULONG pulDepth, DEVINST dnDevInst, ULONG ulFlags)
01671 {
01672     TRACE("%p %lx %lx\n", pulDepth, dnDevInst, ulFlags);
01673     return CM_Get_Depth_Ex(pulDepth, dnDevInst, ulFlags, NULL);
01674 }
01675 
01676 
01677 /***********************************************************************
01678  * CM_Get_Depth_Ex [SETUPAPI.@]
01679  */
01680 CONFIGRET WINAPI CM_Get_Depth_Ex(
01681     PULONG pulDepth, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
01682 {
01683     RPC_BINDING_HANDLE BindingHandle = NULL;
01684     HSTRING_TABLE StringTable = NULL;
01685     LPWSTR lpDevInst;
01686     CONFIGRET ret;
01687 
01688     TRACE("%p %lx %lx %lx\n",
01689           pulDepth, dnDevInst, ulFlags, hMachine);
01690 
01691     if (pulDepth == NULL)
01692         return CR_INVALID_POINTER;
01693 
01694     if (dnDevInst == 0)
01695         return CR_INVALID_DEVINST;
01696 
01697     if (ulFlags != 0)
01698         return CR_INVALID_FLAG;
01699 
01700     if (hMachine != NULL)
01701     {
01702         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
01703         if (BindingHandle == NULL)
01704             return CR_FAILURE;
01705 
01706         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
01707         if (StringTable == 0)
01708             return CR_FAILURE;
01709     }
01710     else
01711     {
01712         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
01713             return CR_FAILURE;
01714     }
01715 
01716     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
01717     if (lpDevInst == NULL)
01718         return CR_INVALID_DEVNODE;
01719 
01720     RpcTryExcept
01721     {
01722         ret = PNP_GetDepth(BindingHandle,
01723                            lpDevInst,
01724                            pulDepth,
01725                            ulFlags);
01726     }
01727     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
01728     {
01729         ret = RpcStatusToCmStatus(RpcExceptionCode());
01730     }
01731     RpcEndExcept;
01732 
01733     return ret;
01734 }
01735 
01736 
01737 /***********************************************************************
01738  * CM_Get_DevNode_Custom_PropertyA [SETUPAPI.@]
01739  */
01740 CONFIGRET WINAPI CM_Get_DevNode_Custom_PropertyA(
01741     DEVINST dnDevInst, PCSTR pszCustomPropertyName, PULONG pulRegDataType,
01742     PVOID Buffer, PULONG pulLength, ULONG ulFlags)
01743 {
01744     TRACE("%lx %s %p %p %p %lx\n", dnDevInst, pszCustomPropertyName,
01745           pulRegDataType, Buffer, pulLength, ulFlags);
01746     return CM_Get_DevNode_Custom_Property_ExA(dnDevInst, pszCustomPropertyName,
01747                                               pulRegDataType, Buffer,
01748                                               pulLength, ulFlags, NULL);
01749 }
01750 
01751 
01752 /***********************************************************************
01753  * CM_Get_DevNode_Custom_PropertyW [SETUPAPI.@]
01754  */
01755 CONFIGRET WINAPI CM_Get_DevNode_Custom_PropertyW(
01756     DEVINST dnDevInst, PCWSTR pszCustomPropertyName, PULONG pulRegDataType,
01757     PVOID Buffer, PULONG pulLength, ULONG ulFlags)
01758 {
01759     TRACE("%lx %s %p %p %p %lx\n", dnDevInst, debugstr_w(pszCustomPropertyName),
01760           pulRegDataType, Buffer, pulLength, ulFlags);
01761     return CM_Get_DevNode_Custom_Property_ExW(dnDevInst, pszCustomPropertyName,
01762                                               pulRegDataType, Buffer,
01763                                               pulLength, ulFlags, NULL);
01764 }
01765 
01766 
01767 /***********************************************************************
01768  * CM_Get_DevNode_Custom_Property_ExA [SETUPAPI.@]
01769  */
01770 CONFIGRET WINAPI CM_Get_DevNode_Custom_Property_ExA(
01771     DEVINST dnDevInst, PCSTR pszCustomPropertyName, PULONG pulRegDataType,
01772     PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
01773 {
01774     LPWSTR pszPropertyNameW = NULL;
01775     PVOID BufferW;
01776     ULONG ulLengthW;
01777     ULONG ulDataType = REG_NONE;
01778     CONFIGRET ret;
01779 
01780     TRACE("%lx %s %p %p %p %lx %p\n", dnDevInst, pszCustomPropertyName,
01781           pulRegDataType, Buffer, pulLength, ulFlags, hMachine);
01782 
01783     if (!pulLength)
01784         return CR_INVALID_POINTER;
01785 
01786     ulLengthW = *pulLength * sizeof(WCHAR);
01787     BufferW = HeapAlloc(GetProcessHeap(), 0, ulLengthW);
01788     if (!BufferW)
01789         return CR_OUT_OF_MEMORY;
01790 
01791     pszPropertyNameW = pSetupMultiByteToUnicode(pszCustomPropertyName,
01792                                                 CP_ACP);
01793     if (pszPropertyNameW == NULL)
01794     {
01795         HeapFree(GetProcessHeap(), 0, BufferW);
01796         return CR_OUT_OF_MEMORY;
01797     }
01798 
01799     ret = CM_Get_DevNode_Custom_Property_ExW(dnDevInst,
01800                                              pszPropertyNameW,
01801                                              &ulDataType,
01802                                              BufferW,
01803                                              &ulLengthW,
01804                                              ulFlags,
01805                                              hMachine);
01806     if (ret == CR_SUCCESS)
01807     {
01808         if (ulDataType == REG_SZ ||
01809             ulDataType == REG_EXPAND_SZ ||
01810             ulDataType == REG_MULTI_SZ)
01811         {
01812             /* Do W->A conversion */
01813             *pulLength = WideCharToMultiByte(CP_ACP,
01814                                              0,
01815                                              BufferW,
01816                                              lstrlenW(BufferW) + 1,
01817                                              Buffer,
01818                                              *pulLength,
01819                                              NULL,
01820                                              NULL);
01821             if (*pulLength == 0)
01822                 ret = CR_FAILURE;
01823         }
01824         else
01825         {
01826             /* Directly copy the value */
01827             if (ulLengthW <= *pulLength)
01828                 memcpy(Buffer, BufferW, ulLengthW);
01829             else
01830             {
01831                 *pulLength = ulLengthW;
01832                 ret = CR_BUFFER_SMALL;
01833             }
01834         }
01835     }
01836 
01837     if (pulRegDataType)
01838         *pulRegDataType = ulDataType;
01839 
01840     HeapFree(GetProcessHeap(), 0, BufferW);
01841     MyFree(pszPropertyNameW);
01842 
01843     return ret;
01844 }
01845 
01846 
01847 /***********************************************************************
01848  * CM_Get_DevNode_Custom_Property_ExW [SETUPAPI.@]
01849  */
01850 CONFIGRET WINAPI CM_Get_DevNode_Custom_Property_ExW(
01851     DEVINST dnDevInst, PCWSTR pszCustomPropertyName, PULONG pulRegDataType,
01852     PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
01853 {
01854     RPC_BINDING_HANDLE BindingHandle = NULL;
01855     HSTRING_TABLE StringTable = NULL;
01856     LPWSTR lpDevInst;
01857     ULONG ulDataType = REG_NONE;
01858     ULONG ulTransferLength;
01859     CONFIGRET ret = CR_SUCCESS;
01860 
01861     TRACE("%lx %s %p %p %p %lx %p\n", dnDevInst,
01862           debugstr_w(pszCustomPropertyName), pulRegDataType, Buffer,
01863           pulLength, ulFlags, hMachine);
01864 
01865     if (dnDevInst == 0)
01866         return CR_INVALID_DEVNODE;
01867 
01868     if (pszCustomPropertyName == NULL ||
01869         pulLength == NULL ||
01870         *pulLength == 0)
01871         return CR_INVALID_POINTER;
01872 
01873     if (ulFlags & ~CM_CUSTOMDEVPROP_BITS)
01874         return CR_INVALID_FLAG;
01875 
01876     if (hMachine != NULL)
01877     {
01878         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
01879         if (BindingHandle == NULL)
01880             return CR_FAILURE;
01881 
01882         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
01883         if (StringTable == 0)
01884             return CR_FAILURE;
01885     }
01886     else
01887     {
01888         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
01889             return CR_FAILURE;
01890     }
01891 
01892     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
01893     if (lpDevInst == NULL)
01894         return CR_INVALID_DEVNODE;
01895 
01896     ulTransferLength = *pulLength;
01897 
01898     RpcTryExcept
01899     {
01900         ret = PNP_GetCustomDevProp(BindingHandle,
01901                                    lpDevInst,
01902                                    (LPWSTR)pszCustomPropertyName,
01903                                    &ulDataType,
01904                                    Buffer,
01905                                    &ulTransferLength,
01906                                    pulLength,
01907                                    ulFlags);
01908     }
01909     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
01910     {
01911         ret = RpcStatusToCmStatus(RpcExceptionCode());
01912     }
01913     RpcEndExcept;
01914 
01915     if (ret == CR_SUCCESS)
01916     {
01917         if (pulRegDataType != NULL)
01918             *pulRegDataType = ulDataType;
01919     }
01920 
01921     return ret;
01922 }
01923 
01924 
01925 /***********************************************************************
01926  * CM_Get_DevNode_Registry_PropertyA [SETUPAPI.@]
01927  */
01928 CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyA(
01929     DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
01930     PVOID Buffer, PULONG pulLength, ULONG ulFlags)
01931 {
01932     TRACE("%lx %lu %p %p %p %lx\n",
01933           dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
01934 
01935     return CM_Get_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
01936                                                 pulRegDataType, Buffer,
01937                                                 pulLength, ulFlags, NULL);
01938 }
01939 
01940 
01941 /***********************************************************************
01942  * CM_Get_DevNode_Registry_PropertyW [SETUPAPI.@]
01943  */
01944 CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyW(
01945     DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
01946     PVOID Buffer, PULONG pulLength, ULONG ulFlags)
01947 {
01948     TRACE("%lx %lu %p %p %p %lx\n",
01949           dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
01950 
01951     return CM_Get_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
01952                                                 pulRegDataType, Buffer,
01953                                                 pulLength, ulFlags, NULL);
01954 }
01955 
01956 
01957 /***********************************************************************
01958  * CM_Get_DevNode_Registry_Property_ExA [SETUPAPI.@]
01959  */
01960 CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExA(
01961     DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
01962     PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
01963 {
01964     PVOID BufferW;
01965     ULONG LengthW;
01966     ULONG ulDataType = REG_NONE;
01967     CONFIGRET ret;
01968 
01969     TRACE("%lx %lu %p %p %p %lx %lx\n",
01970           dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
01971           ulFlags, hMachine);
01972 
01973     if (!pulLength)
01974         return CR_INVALID_POINTER;
01975 
01976     LengthW = *pulLength * sizeof(WCHAR);
01977     BufferW = HeapAlloc(GetProcessHeap(), 0, LengthW);
01978 
01979     if (!BufferW)
01980         return CR_OUT_OF_MEMORY;
01981 
01982     ret = CM_Get_DevNode_Registry_Property_ExW(dnDevInst,
01983                                                ulProperty,
01984                                                &ulDataType,
01985                                                BufferW,
01986                                                &LengthW,
01987                                                ulFlags,
01988                                                hMachine);
01989 
01990     if (ret == CR_SUCCESS)
01991     {
01992         if (ulDataType == REG_SZ ||
01993             ulDataType == REG_EXPAND_SZ ||
01994             ulDataType == REG_MULTI_SZ)
01995         {
01996             /* Do W->A conversion */
01997             *pulLength = WideCharToMultiByte(CP_ACP,
01998                                              0,
01999                                              BufferW,
02000                                              lstrlenW(BufferW) + 1,
02001                                              Buffer,
02002                                              *pulLength,
02003                                              NULL,
02004                                              NULL);
02005             if (*pulLength == 0)
02006                 ret = CR_FAILURE;
02007         }
02008         else
02009         {
02010             /* Directly copy the value */
02011             if (LengthW <= *pulLength)
02012                 memcpy(Buffer, BufferW, LengthW);
02013             else
02014             {
02015                 *pulLength = LengthW;
02016                 ret = CR_BUFFER_SMALL;
02017             }
02018         }
02019     }
02020 
02021     if (pulRegDataType)
02022         *pulRegDataType = ulDataType;
02023 
02024     HeapFree(GetProcessHeap(), 0, BufferW);
02025 
02026     return ret;
02027 }
02028 
02029 
02030 /***********************************************************************
02031  * CM_Get_DevNode_Registry_Property_ExW [SETUPAPI.@]
02032  */
02033 CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExW(
02034     DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
02035     PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
02036 {
02037     RPC_BINDING_HANDLE BindingHandle = NULL;
02038     HSTRING_TABLE StringTable = NULL;
02039     CONFIGRET ret = CR_SUCCESS;
02040     LPWSTR lpDevInst;
02041     ULONG ulDataType = REG_NONE;
02042     ULONG ulTransferLength = 0;
02043 
02044     TRACE("%lx %lu %p %p %p %lx %lx\n",
02045           dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
02046           ulFlags, hMachine);
02047 
02048     if (dnDevInst == 0)
02049         return CR_INVALID_DEVNODE;
02050 
02051     if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
02052         return CR_INVALID_PROPERTY;
02053 
02054     /* pulRegDataType is optional */
02055 
02056     /* Buffer is optional */
02057 
02058     if (pulLength == NULL)
02059         return CR_INVALID_POINTER;
02060 
02061     if (*pulLength == 0)
02062         return CR_INVALID_POINTER;
02063 
02064     if (ulFlags != 0)
02065         return CR_INVALID_FLAG;
02066 
02067     if (hMachine != NULL)
02068     {
02069         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
02070         if (BindingHandle == NULL)
02071             return CR_FAILURE;
02072 
02073         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
02074         if (StringTable == 0)
02075             return CR_FAILURE;
02076     }
02077     else
02078     {
02079         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
02080             return CR_FAILURE;
02081     }
02082 
02083     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
02084     if (lpDevInst == NULL)
02085         return CR_INVALID_DEVNODE;
02086 
02087     ulTransferLength = *pulLength;
02088 
02089     RpcTryExcept
02090     {
02091         ret = PNP_GetDeviceRegProp(BindingHandle,
02092                                    lpDevInst,
02093                                    ulProperty,
02094                                    &ulDataType,
02095                                    Buffer,
02096                                    &ulTransferLength,
02097                                    pulLength,
02098                                    ulFlags);
02099     }
02100     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
02101     {
02102         ret = RpcStatusToCmStatus(RpcExceptionCode());
02103     }
02104     RpcEndExcept;
02105 
02106     if (ret == CR_SUCCESS)
02107     {
02108         if (pulRegDataType != NULL)
02109             *pulRegDataType = ulDataType;
02110     }
02111 
02112     return ret;
02113 }
02114 
02115 
02116 /***********************************************************************
02117  * CM_Get_DevNode_Status [SETUPAPI.@]
02118  */
02119 CONFIGRET WINAPI CM_Get_DevNode_Status(
02120     PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst,
02121     ULONG ulFlags)
02122 {
02123     TRACE("%p %p %lx %lx\n",
02124           pulStatus, pulProblemNumber, dnDevInst, ulFlags);
02125     return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber, dnDevInst,
02126                                     ulFlags, NULL);
02127 }
02128 
02129 
02130 /***********************************************************************
02131  * CM_Get_DevNode_Status_Ex [SETUPAPI.@]
02132  */
02133 CONFIGRET WINAPI
02134 CM_Get_DevNode_Status_Ex(
02135     PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst,
02136     ULONG ulFlags, HMACHINE hMachine)
02137 {
02138     RPC_BINDING_HANDLE BindingHandle = NULL;
02139     HSTRING_TABLE StringTable = NULL;
02140     LPWSTR lpDevInst;
02141     CONFIGRET ret;
02142 
02143     TRACE("%p %p %lx %lx %lx\n",
02144           pulStatus, pulProblemNumber, dnDevInst, ulFlags, hMachine);
02145 
02146     if (pulStatus == NULL || pulProblemNumber == NULL)
02147         return CR_INVALID_POINTER;
02148 
02149     if (dnDevInst == 0)
02150         return CR_INVALID_DEVINST;
02151 
02152     if (ulFlags != 0)
02153         return CR_INVALID_FLAG;
02154 
02155     if (hMachine != NULL)
02156     {
02157         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
02158         if (BindingHandle == NULL)
02159             return CR_FAILURE;
02160 
02161         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
02162         if (StringTable == 0)
02163             return CR_FAILURE;
02164     }
02165     else
02166     {
02167         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
02168             return CR_FAILURE;
02169     }
02170 
02171     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
02172     if (lpDevInst == NULL)
02173         return CR_INVALID_DEVNODE;
02174 
02175     RpcTryExcept
02176     {
02177         ret = PNP_GetDeviceStatus(BindingHandle,
02178                                   lpDevInst,
02179                                   pulStatus,
02180                                   pulProblemNumber,
02181                                   ulFlags);
02182     }
02183     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
02184     {
02185         ret = RpcStatusToCmStatus(RpcExceptionCode());
02186     }
02187     RpcEndExcept;
02188 
02189     return ret;
02190 }
02191 
02192 
02193 /***********************************************************************
02194  * CM_Get_Device_IDA [SETUPAPI.@]
02195  */
02196 CONFIGRET WINAPI CM_Get_Device_IDA(
02197     DEVINST dnDevInst, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
02198 {
02199     TRACE("%lx %p %ld %ld\n",
02200           dnDevInst, Buffer, BufferLen, ulFlags);
02201     return CM_Get_Device_ID_ExA(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
02202 }
02203 
02204 
02205 /***********************************************************************
02206  * CM_Get_Device_IDW [SETUPAPI.@]
02207  */
02208 CONFIGRET WINAPI CM_Get_Device_IDW(
02209     DEVINST dnDevInst, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
02210 {
02211     TRACE("%lx %p %ld %ld\n",
02212           dnDevInst, Buffer, BufferLen, ulFlags);
02213     return CM_Get_Device_ID_ExW(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
02214 }
02215 
02216 
02217 /***********************************************************************
02218  * CM_Get_Device_ID_ExA [SETUPAPI.@]
02219  */
02220 CONFIGRET WINAPI CM_Get_Device_ID_ExA(
02221     DEVINST dnDevInst, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
02222     HMACHINE hMachine)
02223 {
02224     WCHAR szBufferW[MAX_DEVICE_ID_LEN];
02225     CONFIGRET ret = CR_SUCCESS;
02226 
02227     TRACE("%lx %p %ld %ld %lx\n",
02228           dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
02229 
02230     if (Buffer == NULL)
02231         return CR_INVALID_POINTER;
02232 
02233     ret = CM_Get_Device_ID_ExW(dnDevInst,
02234                                szBufferW,
02235                                MAX_DEVICE_ID_LEN,
02236                                ulFlags,
02237                                hMachine);
02238     if (ret == CR_SUCCESS)
02239     {
02240         if (WideCharToMultiByte(CP_ACP,
02241                                 0,
02242                                 szBufferW,
02243                                 lstrlenW(szBufferW) + 1,
02244                                 Buffer,
02245                                 BufferLen,
02246                                 NULL,
02247                                 NULL) == 0)
02248             ret = CR_FAILURE;
02249     }
02250 
02251     return ret;
02252 }
02253 
02254 
02255 /***********************************************************************
02256  * CM_Get_Device_ID_ExW [SETUPAPI.@]
02257  */
02258 CONFIGRET WINAPI CM_Get_Device_ID_ExW(
02259     DEVINST dnDevInst, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
02260     HMACHINE hMachine)
02261 {
02262     HSTRING_TABLE StringTable = NULL;
02263 
02264     TRACE("%lx %p %ld %ld %lx\n",
02265           dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
02266 
02267     if (dnDevInst == 0)
02268         return CR_INVALID_DEVINST;
02269 
02270     if (Buffer == NULL)
02271         return CR_INVALID_POINTER;
02272 
02273     if (ulFlags != 0)
02274         return CR_INVALID_FLAG;
02275 
02276     if (hMachine != NULL)
02277     {
02278         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
02279         if (StringTable == NULL)
02280             return CR_FAILURE;
02281     }
02282     else
02283     {
02284         if (!PnpGetLocalHandles(NULL, &StringTable))
02285             return CR_FAILURE;
02286     }
02287 
02288     if (!pSetupStringTableStringFromIdEx(StringTable,
02289                                          dnDevInst,
02290                                          Buffer,
02291                                          &BufferLen))
02292         return CR_FAILURE;
02293 
02294     return CR_SUCCESS;
02295 }
02296 
02297 
02298 /***********************************************************************
02299  * CM_Get_Device_ID_ListA [SETUPAPI.@]
02300  */
02301 CONFIGRET WINAPI CM_Get_Device_ID_ListA(
02302     PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
02303 {
02304     TRACE("%p %p %ld %ld\n", pszFilter, Buffer, BufferLen, ulFlags);
02305     return CM_Get_Device_ID_List_ExA(pszFilter, Buffer, BufferLen,
02306                                      ulFlags, NULL);
02307 }
02308 
02309 
02310 /***********************************************************************
02311  * CM_Get_Device_ID_ListW [SETUPAPI.@]
02312  */
02313 CONFIGRET WINAPI CM_Get_Device_ID_ListW(
02314     PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
02315 {
02316     TRACE("%p %p %ld %ld\n", pszFilter, Buffer, BufferLen, ulFlags);
02317     return CM_Get_Device_ID_List_ExW(pszFilter, Buffer, BufferLen,
02318                                      ulFlags, NULL);
02319 }
02320 
02321 
02322 /***********************************************************************
02323  * CM_Get_Device_ID_List_ExA [SETUPAPI.@]
02324  */
02325 CONFIGRET WINAPI CM_Get_Device_ID_List_ExA(
02326     PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
02327     HMACHINE hMachine)
02328 {
02329     LPWSTR BufferW = NULL;
02330     LPWSTR pszFilterW = NULL;
02331     CONFIGRET ret = CR_SUCCESS;
02332 
02333     TRACE("%p %p %ld %ld %lx\n",
02334           pszFilter, Buffer, BufferLen, ulFlags, hMachine);
02335 
02336     BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
02337     if (BufferW == NULL)
02338         return CR_OUT_OF_MEMORY;
02339 
02340     if (pszFilter == NULL)
02341     {
02342         ret = CM_Get_Device_ID_List_ExW(NULL,
02343                                         BufferW,
02344                                         BufferLen,
02345                                         ulFlags,
02346                                         hMachine);
02347     }
02348     else
02349     {
02350         if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
02351         {
02352             ret = CR_INVALID_DEVICE_ID;
02353             goto Done;
02354         }
02355 
02356         ret = CM_Get_Device_ID_List_ExW(pszFilterW,
02357                                         BufferW,
02358                                         BufferLen,
02359                                         ulFlags,
02360                                         hMachine);
02361 
02362         MyFree(pszFilterW);
02363     }
02364 
02365     if (WideCharToMultiByte(CP_ACP,
02366                             0,
02367                             BufferW,
02368                             lstrlenW(BufferW) + 1,
02369                             Buffer,
02370                             BufferLen,
02371                             NULL,
02372                             NULL) == 0)
02373         ret = CR_FAILURE;
02374 
02375 Done:
02376     MyFree(BufferW);
02377 
02378     return ret;
02379 }
02380 
02381 
02382 /***********************************************************************
02383  * CM_Get_Device_ID_List_ExW [SETUPAPI.@]
02384  */
02385 CONFIGRET WINAPI CM_Get_Device_ID_List_ExW(
02386     PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
02387     HMACHINE hMachine)
02388 {
02389     RPC_BINDING_HANDLE BindingHandle = NULL;
02390     CONFIGRET ret;
02391 
02392     TRACE("%p %p %ld %ld %lx\n",
02393           pszFilter, Buffer, BufferLen, ulFlags, hMachine);
02394 
02395     if (Buffer == NULL || BufferLen == 0)
02396         return CR_INVALID_POINTER;
02397 
02398     if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
02399         return CR_INVALID_FLAG;
02400 
02401     if (hMachine != NULL)
02402     {
02403         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
02404         if (BindingHandle == NULL)
02405             return CR_FAILURE;
02406     }
02407     else
02408     {
02409         if (!PnpGetLocalHandles(&BindingHandle, NULL))
02410             return CR_FAILURE;
02411     }
02412 
02413     *Buffer = 0;
02414 
02415     RpcTryExcept
02416     {
02417         ret = PNP_GetDeviceList(BindingHandle,
02418                                 (LPWSTR)pszFilter,
02419                                 Buffer,
02420                                 &BufferLen,
02421                                 ulFlags);
02422     }
02423     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
02424     {
02425         ret = RpcStatusToCmStatus(RpcExceptionCode());
02426     }
02427     RpcEndExcept;
02428 
02429     return ret;
02430 }
02431 
02432 
02433 /***********************************************************************
02434  * CM_Get_Device_ID_List_SizeA [SETUPAPI.@]
02435  */
02436 CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(
02437     PULONG pulLen, PCSTR pszFilter, ULONG ulFlags)
02438 {
02439     TRACE("%p %s %ld\n", pulLen, pszFilter, ulFlags);
02440     return CM_Get_Device_ID_List_Size_ExA(pulLen, pszFilter, ulFlags, NULL);
02441 }
02442 
02443 
02444 /***********************************************************************
02445  * CM_Get_Device_ID_List_SizeW [SETUPAPI.@]
02446  */
02447 CONFIGRET WINAPI CM_Get_Device_ID_List_SizeW(
02448     PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags)
02449 {
02450     TRACE("%p %s %ld\n", pulLen, debugstr_w(pszFilter), ulFlags);
02451     return CM_Get_Device_ID_List_Size_ExW(pulLen, pszFilter, ulFlags, NULL);
02452 }
02453 
02454 
02455 /***********************************************************************
02456  * CM_Get_Device_ID_List_Size_ExA [SETUPAPI.@]
02457  */
02458 CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExA(
02459     PULONG pulLen, PCSTR pszFilter, ULONG ulFlags, HMACHINE hMachine)
02460 {
02461     LPWSTR pszFilterW = NULL;
02462     CONFIGRET ret = CR_SUCCESS;
02463 
02464     FIXME("%p %s %lx %lx\n", pulLen, pszFilter, ulFlags, hMachine);
02465 
02466     if (pszFilter == NULL)
02467     {
02468         ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
02469                                              NULL,
02470                                              ulFlags,
02471                                              hMachine);
02472     }
02473     else
02474     {
02475         if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
02476             return CR_INVALID_DEVICE_ID;
02477 
02478         ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
02479                                              pszFilterW,
02480                                              ulFlags,
02481                                              hMachine);
02482 
02483         MyFree(pszFilterW);
02484     }
02485 
02486     return ret;
02487 }
02488 
02489 
02490 /***********************************************************************
02491  * CM_Get_Device_ID_List_Size_ExW [SETUPAPI.@]
02492  */
02493 CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExW(
02494     PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags, HMACHINE hMachine)
02495 {
02496     RPC_BINDING_HANDLE BindingHandle = NULL;
02497     CONFIGRET ret;
02498 
02499     FIXME("%p %s %ld %lx\n", pulLen, debugstr_w(pszFilter), ulFlags, hMachine);
02500 
02501     if (pulLen == NULL)
02502         return CR_INVALID_POINTER;
02503 
02504     if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
02505         return CR_INVALID_FLAG;
02506 
02507     if (hMachine != NULL)
02508     {
02509         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
02510         if (BindingHandle == NULL)
02511             return CR_FAILURE;
02512     }
02513     else
02514     {
02515         if (!PnpGetLocalHandles(&BindingHandle, NULL))
02516             return CR_FAILURE;
02517     }
02518 
02519     *pulLen = 0;
02520 
02521     RpcTryExcept
02522     {
02523         ret = PNP_GetDeviceListSize(BindingHandle,
02524                                     (LPWSTR)pszFilter,
02525                                     pulLen,
02526                                     ulFlags);
02527     }
02528     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
02529     {
02530         ret = RpcStatusToCmStatus(RpcExceptionCode());
02531     }
02532     RpcEndExcept;
02533 
02534     return ret;
02535 }
02536 
02537 
02538 /***********************************************************************
02539  * CM_Get_Device_ID_Size [SETUPAPI.@]
02540  */
02541 CONFIGRET WINAPI CM_Get_Device_ID_Size(
02542     PULONG pulLen, DEVINST dnDevInst, ULONG ulFlags)
02543 {
02544     TRACE("%p %lx %lx\n", pulLen, dnDevInst, ulFlags);
02545     return CM_Get_Device_ID_Size_Ex(pulLen, dnDevInst, ulFlags, NULL);
02546 }
02547 
02548 
02549 /***********************************************************************
02550  * CM_Get_Device_ID_Size_Ex [SETUPAPI.@]
02551  */
02552 CONFIGRET WINAPI CM_Get_Device_ID_Size_Ex(
02553     PULONG pulLen, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
02554 {
02555     HSTRING_TABLE StringTable = NULL;
02556     LPWSTR DeviceId;
02557 
02558     TRACE("%p %lx %lx %lx\n", pulLen, dnDevInst, ulFlags, hMachine);
02559 
02560     if (pulLen == NULL)
02561         return CR_INVALID_POINTER;
02562 
02563     if (dnDevInst == 0)
02564         return CR_INVALID_DEVINST;
02565 
02566     if (ulFlags != 0)
02567         return CR_INVALID_FLAG;
02568 
02569     if (hMachine != NULL)
02570     {
02571         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
02572         if (StringTable == NULL)
02573             return CR_FAILURE;
02574     }
02575     else
02576     {
02577         if (!PnpGetLocalHandles(NULL, &StringTable))
02578             return CR_FAILURE;
02579     }
02580 
02581     DeviceId = pSetupStringTableStringFromId(StringTable, dnDevInst);
02582     if (DeviceId == NULL)
02583     {
02584         *pulLen = 0;
02585         return CR_SUCCESS;
02586     }
02587 
02588     *pulLen = lstrlenW(DeviceId);
02589 
02590     return CR_SUCCESS;
02591 }
02592 
02593 
02594 /***********************************************************************
02595  * CM_Get_Device_Interface_AliasA [SETUPAPI.@]
02596  */
02597 CONFIGRET WINAPI CM_Get_Device_Interface_AliasA(
02598     LPCSTR pszDeviceInterface, LPGUID AliasInterfaceGuid,
02599     LPSTR pszAliasDeviceInterface, PULONG pulLength, ULONG ulFlags)
02600 {
02601     TRACE("%p %p %p %p %lu\n", pszDeviceInterface, AliasInterfaceGuid,
02602           pszAliasDeviceInterface, pulLength, ulFlags);
02603 
02604     return CM_Get_Device_Interface_Alias_ExA(pszDeviceInterface,
02605         AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
02606         ulFlags, NULL);
02607 }
02608 
02609 
02610 /***********************************************************************
02611  * CM_Get_Device_Interface_AliasW [SETUPAPI.@]
02612  */
02613 CONFIGRET WINAPI CM_Get_Device_Interface_AliasW(
02614     LPCWSTR pszDeviceInterface, LPGUID AliasInterfaceGuid,
02615     LPWSTR pszAliasDeviceInterface, PULONG pulLength, ULONG ulFlags)
02616 {
02617     TRACE("%p %p %p %p %lu\n", pszDeviceInterface, AliasInterfaceGuid,
02618           pszAliasDeviceInterface, pulLength, ulFlags);
02619 
02620     return CM_Get_Device_Interface_Alias_ExW(pszDeviceInterface,
02621         AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
02622         ulFlags, NULL);
02623 }
02624 
02625 
02626 /***********************************************************************
02627  * CM_Get_Device_Interface_Alias_ExA [SETUPAPI.@]
02628  */
02629 CONFIGRET WINAPI CM_Get_Device_Interface_Alias_ExA(
02630     LPCSTR pszDeviceInterface, LPGUID AliasInterfaceGuid, LPSTR pszAliasDeviceInterface,
02631     PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
02632 {
02633     FIXME("%p %p %p %p %lu %lx\n", pszDeviceInterface, AliasInterfaceGuid,
02634           pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
02635 
02636     return CR_CALL_NOT_IMPLEMENTED;
02637 }
02638 
02639 
02640 /***********************************************************************
02641  * CM_Get_Device_Interface_Alias_ExW [SETUPAPI.@]
02642  */
02643 CONFIGRET WINAPI CM_Get_Device_Interface_Alias_ExW(
02644     LPCWSTR pszDeviceInterface, LPGUID AliasInterfaceGuid, LPWSTR pszAliasDeviceInterface,
02645     PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
02646 {
02647     RPC_BINDING_HANDLE BindingHandle = NULL;
02648     ULONG ulTransferLength;
02649     CONFIGRET ret = CR_SUCCESS;
02650 
02651     TRACE("%p %p %p %p %lu %lx\n", pszDeviceInterface, AliasInterfaceGuid,
02652           pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
02653 
02654     if (pszDeviceInterface == NULL ||
02655         AliasInterfaceGuid == NULL ||
02656         pszAliasDeviceInterface == NULL ||
02657         pulLength == NULL)
02658         return CR_INVALID_POINTER;
02659 
02660     if (ulFlags != 0)
02661         return CR_INVALID_FLAG;
02662 
02663     if (hMachine != NULL)
02664     {
02665         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
02666         if (BindingHandle == NULL)
02667             return CR_FAILURE;
02668     }
02669     else
02670     {
02671         if (!PnpGetLocalHandles(&BindingHandle, NULL))
02672             return CR_FAILURE;
02673     }
02674 
02675     ulTransferLength = *pulLength;
02676 
02677     RpcTryExcept
02678     {
02679         ret = PNP_GetInterfaceDeviceAlias(BindingHandle,
02680                                           (LPWSTR)pszDeviceInterface,
02681                                           AliasInterfaceGuid,
02682                                           pszAliasDeviceInterface,
02683                                           pulLength,
02684                                           &ulTransferLength,
02685                                           0);
02686     }
02687     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
02688     {
02689         ret = RpcStatusToCmStatus(RpcExceptionCode());
02690     }
02691     RpcEndExcept;
02692 
02693     return ret;
02694 }
02695 
02696 
02697 /***********************************************************************
02698  *      CM_Get_Device_Interface_ListA (SETUPAPI.@)
02699  */
02700 CONFIGRET WINAPI CM_Get_Device_Interface_ListA(
02701     LPGUID InterfaceClassGuid, DEVINSTID_A pDeviceID, PCHAR Buffer,
02702     ULONG BufferLen, ULONG ulFlags)
02703 {
02704     TRACE("%s %s %p %lu 0x%08lx\n", debugstr_guid(InterfaceClassGuid),
02705           pDeviceID, Buffer, BufferLen, ulFlags);
02706 
02707     return CM_Get_Device_Interface_List_ExA(InterfaceClassGuid, pDeviceID,
02708                                             Buffer, BufferLen, ulFlags, NULL);
02709 }
02710 
02711 
02712 /***********************************************************************
02713  *      CM_Get_Device_Interface_ListW (SETUPAPI.@)
02714  */
02715 CONFIGRET WINAPI CM_Get_Device_Interface_ListW(
02716     LPGUID InterfaceClassGuid, DEVINSTID_W pDeviceID, PWCHAR Buffer,
02717     ULONG BufferLen, ULONG ulFlags)
02718 {
02719     TRACE("%s %s %p %lu 0x%08lx\n", debugstr_guid(InterfaceClassGuid),
02720           debugstr_w(pDeviceID), Buffer, BufferLen, ulFlags);
02721 
02722     return CM_Get_Device_Interface_List_ExW(InterfaceClassGuid, pDeviceID,
02723                                             Buffer, BufferLen, ulFlags, NULL);
02724 }
02725 
02726 
02727 /***********************************************************************
02728  *      CM_Get_Device_Interface_List_ExA (SETUPAPI.@)
02729  */
02730 CONFIGRET WINAPI CM_Get_Device_Interface_List_ExA(
02731     LPGUID InterfaceClassGuid, DEVINSTID_A pDeviceID, PCHAR Buffer,
02732     ULONG BufferLen, ULONG ulFlags, HMACHINE hMachine)
02733 {
02734     DEVINSTID_W pDeviceIdW = NULL;
02735     PWCHAR BufferW = NULL;
02736     CONFIGRET ret = CR_SUCCESS;
02737 
02738     TRACE("%s %s %p %lu 0x%08lx %p\n", debugstr_guid(InterfaceClassGuid),
02739           pDeviceID, Buffer, BufferLen, ulFlags, hMachine);
02740 
02741     if (Buffer == NULL ||
02742         BufferLen == 0)
02743         return CR_INVALID_POINTER;
02744 
02745     if (pDeviceID != NULL)
02746     {
02747         if (!pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIdW))
02748             return CR_INVALID_DEVICE_ID;
02749     }
02750 
02751     BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
02752     if (BufferW == NULL)
02753     {
02754         ret = CR_OUT_OF_MEMORY;
02755         goto Done;
02756     }
02757 
02758     ret = CM_Get_Device_Interface_List_ExW(InterfaceClassGuid, pDeviceIdW,
02759                                            BufferW, BufferLen, ulFlags,
02760                                            hMachine);
02761     if (ret != CR_SUCCESS)
02762         goto Done;
02763 
02764     if (WideCharToMultiByte(CP_ACP,
02765                             0,
02766                             BufferW,
02767                             lstrlenW(BufferW) + 1,
02768                             Buffer,
02769                             BufferLen,
02770                             NULL,
02771                             NULL) == 0)
02772         ret = CR_FAILURE;
02773 
02774 Done:
02775     if (BufferW != NULL)
02776         MyFree(BufferW);
02777 
02778     if (pDeviceIdW != NULL)
02779         MyFree(pDeviceIdW);
02780 
02781     return ret;
02782 }
02783 
02784 
02785 /***********************************************************************
02786  *      CM_Get_Device_Interface_List_ExW (SETUPAPI.@)
02787  */
02788 CONFIGRET WINAPI CM_Get_Device_Interface_List_ExW(
02789     LPGUID InterfaceClassGuid, DEVINSTID_W pDeviceID, PWCHAR Buffer,
02790     ULONG BufferLen, ULONG ulFlags, HMACHINE hMachine)
02791 {
02792     RPC_BINDING_HANDLE BindingHandle = NULL;
02793     PNP_RPC_BUFFER_SIZE BufferSize = 0;
02794     CONFIGRET ret = CR_SUCCESS;
02795 
02796     TRACE("%s %s %p %lu 0x%08lx %p\n", debugstr_guid(InterfaceClassGuid),
02797           debugstr_w(pDeviceID), Buffer, BufferLen, ulFlags, hMachine);
02798 
02799     if (Buffer == NULL ||
02800         BufferLen == 0)
02801         return CR_INVALID_POINTER;
02802 
02803     if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
02804         return CR_INVALID_FLAG;
02805 
02806     if (hMachine != NULL)
02807     {
02808         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
02809         if (BindingHandle == NULL)
02810             return CR_FAILURE;
02811     }
02812     else
02813     {
02814         if (!PnpGetLocalHandles(&BindingHandle, NULL))
02815             return CR_FAILURE;
02816     }
02817 
02818     *Buffer = 0;
02819     BufferSize = BufferLen;
02820 
02821     RpcTryExcept
02822     {
02823         ret = PNP_GetInterfaceDeviceList(BindingHandle,
02824                                          InterfaceClassGuid,
02825                                          pDeviceID,
02826                                          (LPBYTE)Buffer,
02827                                          &BufferSize,
02828                                          ulFlags);
02829     }
02830     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
02831     {
02832         ret = RpcStatusToCmStatus(RpcExceptionCode());
02833     }
02834     RpcEndExcept;
02835 
02836     return ret;
02837 }
02838 
02839 
02840 /***********************************************************************
02841  *      CM_Get_Device_Interface_List_SizeA (SETUPAPI.@)
02842  */
02843 CONFIGRET WINAPI CM_Get_Device_Interface_List_SizeA(
02844     PULONG pulLen, LPGUID InterfaceClassGuid, DEVINSTID_A pDeviceId,
02845     ULONG ulFlags)
02846 {
02847     TRACE("%p %p %s 0x%08lx\n", pulLen, InterfaceClassGuid,
02848           pDeviceId, ulFlags);
02849 
02850     return CM_Get_Device_Interface_List_Size_ExA(pulLen, InterfaceClassGuid,
02851                                                  pDeviceId, ulFlags, NULL);
02852 }
02853 
02854 
02855 /***********************************************************************
02856  *      CM_Get_Device_Interface_List_SizeW (SETUPAPI.@)
02857  */
02858 CONFIGRET WINAPI CM_Get_Device_Interface_List_SizeW(
02859     PULONG pulLen, LPGUID InterfaceClassGuid, DEVINSTID_W pDeviceId,
02860     ULONG ulFlags)
02861 {
02862     TRACE("%p %p %s 0x%08lx\n", pulLen, InterfaceClassGuid,
02863           debugstr_w(pDeviceId), ulFlags);
02864 
02865     return CM_Get_Device_Interface_List_Size_ExW(pulLen, InterfaceClassGuid,
02866                                                  pDeviceId, ulFlags, NULL);
02867 }
02868 
02869 
02870 /***********************************************************************
02871  *      CM_Get_Device_Interface_List_Size_ExA (SETUPAPI.@)
02872  */
02873 CONFIGRET WINAPI CM_Get_Device_Interface_List_Size_ExA(
02874     PULONG pulLen, LPGUID InterfaceClassGuid, DEVINSTID_A pDeviceId,
02875     ULONG ulFlags, HMACHINE hMachine)
02876 {
02877     DEVINSTID_W pDeviceIdW = NULL;
02878     CONFIGRET ret = CR_SUCCESS;
02879 
02880     TRACE("%p %p %s 0x%08lx %p\n", pulLen, InterfaceClassGuid,
02881           pDeviceId, ulFlags, hMachine);
02882 
02883     if (pulLen == NULL)
02884         return CR_INVALID_POINTER;
02885 
02886     if (pDeviceId != NULL)
02887     {
02888         if (!pSetupCaptureAndConvertAnsiArg(pDeviceId, &pDeviceIdW))
02889             return CR_INVALID_DEVICE_ID;
02890     }
02891 
02892     *pulLen = 0;
02893 
02894     ret = CM_Get_Device_Interface_List_Size_ExW(pulLen, InterfaceClassGuid,
02895                                                 pDeviceIdW, ulFlags, hMachine);
02896 
02897     if (pDeviceIdW != NULL)
02898         MyFree(pDeviceIdW);
02899 
02900     return ret;
02901 }
02902 
02903 
02904 /***********************************************************************
02905  *      CM_Get_Device_Interface_List_Size_ExW (SETUPAPI.@)
02906  */
02907 CONFIGRET WINAPI CM_Get_Device_Interface_List_Size_ExW(
02908     PULONG pulLen, LPGUID InterfaceClassGuid, DEVINSTID_W pDeviceId,
02909     ULONG ulFlags, HMACHINE hMachine)
02910 {
02911     RPC_BINDING_HANDLE BindingHandle = NULL;
02912     CONFIGRET ret = CR_SUCCESS;
02913 
02914     TRACE("%p %p %s 0x%08lx %p\n", pulLen, InterfaceClassGuid,
02915           debugstr_w(pDeviceId), ulFlags, hMachine);
02916 
02917     if (pulLen == NULL)
02918         return CR_INVALID_POINTER;
02919 
02920     if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
02921         return CR_INVALID_FLAG;
02922 
02923     if (hMachine != NULL)
02924     {
02925         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
02926         if (BindingHandle == NULL)
02927             return CR_FAILURE;
02928     }
02929     else
02930     {
02931         if (!PnpGetLocalHandles(&BindingHandle, NULL))
02932             return CR_FAILURE;
02933     }
02934 
02935     *pulLen = 0;
02936 
02937     RpcTryExcept
02938     {
02939         ret = PNP_GetInterfaceDeviceListSize(BindingHandle,
02940                                              pulLen,
02941                                              InterfaceClassGuid,
02942                                              pDeviceId,
02943                                              ulFlags);
02944     }
02945     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
02946     {
02947         ret = RpcStatusToCmStatus(RpcExceptionCode());
02948     }
02949     RpcEndExcept;
02950 
02951     return ret;
02952 }
02953 
02954 
02955 /***********************************************************************
02956  * CM_Get_First_Log_Conf [SETUPAPI.@]
02957  */
02958 CONFIGRET WINAPI CM_Get_First_Log_Conf(
02959     PLOG_CONF plcLogConf, DEVINST dnDevInst, ULONG ulFlags)
02960 {
02961     TRACE("%p %lx %lx\n", plcLogConf, dnDevInst, ulFlags);
02962     return CM_Get_First_Log_Conf_Ex(plcLogConf, dnDevInst, ulFlags, NULL);
02963 }
02964 
02965 
02966 /***********************************************************************
02967  * CM_Get_First_Log_Conf_Ex [SETUPAPI.@]
02968  */
02969 CONFIGRET WINAPI CM_Get_First_Log_Conf_Ex(
02970     PLOG_CONF plcLogConf, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
02971 {
02972     RPC_BINDING_HANDLE BindingHandle = NULL;
02973     HSTRING_TABLE StringTable = NULL;
02974     LPWSTR lpDevInst = NULL;
02975     CONFIGRET ret = CR_SUCCESS;
02976     ULONG ulTag;
02977     PLOG_CONF_INFO pLogConfInfo;
02978 
02979     FIXME("%p %lx %lx %lx\n", plcLogConf, dnDevInst, ulFlags, hMachine);
02980 
02981     if (dnDevInst == 0)
02982         return CR_INVALID_DEVINST;
02983 
02984     if (ulFlags & ~LOG_CONF_BITS)
02985         return CR_INVALID_FLAG;
02986 
02987     if (plcLogConf)
02988         *plcLogConf = 0;
02989 
02990     if (hMachine != NULL)
02991     {
02992         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
02993         if (BindingHandle == NULL)
02994             return CR_FAILURE;
02995 
02996         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
02997         if (StringTable == 0)
02998             return CR_FAILURE;
02999     }
03000     else
03001     {
03002         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
03003             return CR_FAILURE;
03004     }
03005 
03006     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
03007     if (lpDevInst == NULL)
03008         return CR_INVALID_DEVNODE;
03009 
03010     RpcTryExcept
03011     {
03012         ret = PNP_GetFirstLogConf(BindingHandle,
03013                                   lpDevInst,
03014                                   ulFlags,
03015                                   &ulTag,
03016                                   ulFlags);
03017     }
03018     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03019     {
03020         ret = RpcStatusToCmStatus(RpcExceptionCode());
03021     }
03022     RpcEndExcept;
03023 
03024     if (ret != CR_SUCCESS)
03025         return ret;
03026 
03027     if (plcLogConf)
03028     {
03029         pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
03030         if (pLogConfInfo == NULL)
03031             return CR_OUT_OF_MEMORY;
03032 
03033         pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
03034         pLogConfInfo->dnDevInst = dnDevInst;
03035         pLogConfInfo->ulFlags = ulFlags;
03036         pLogConfInfo->ulTag = ulTag;
03037 
03038         *plcLogConf = (LOG_CONF)pLogConfInfo;
03039     }
03040 
03041     return CR_SUCCESS;
03042 }
03043 
03044 
03045 /***********************************************************************
03046  * CM_Get_Global_State [SETUPAPI.@]
03047  */
03048 CONFIGRET WINAPI CM_Get_Global_State(
03049     PULONG pulState, ULONG ulFlags)
03050 {
03051     TRACE("%p %lx\n", pulState, ulFlags);
03052     return CM_Get_Global_State_Ex(pulState, ulFlags, NULL);
03053 }
03054 
03055 
03056 /***********************************************************************
03057  * CM_Get_Global_State_Ex [SETUPAPI.@]
03058  */
03059 CONFIGRET WINAPI CM_Get_Global_State_Ex(
03060     PULONG pulState, ULONG ulFlags, HMACHINE hMachine)
03061 {
03062     RPC_BINDING_HANDLE BindingHandle = NULL;
03063     CONFIGRET ret;
03064 
03065     TRACE("%p %lx %lx\n", pulState, ulFlags, hMachine);
03066 
03067     if (pulState == NULL)
03068         return CR_INVALID_POINTER;
03069 
03070     if (ulFlags != 0)
03071         return CR_INVALID_FLAG;
03072 
03073     if (hMachine != NULL)
03074     {
03075         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
03076         if (BindingHandle == NULL)
03077             return CR_FAILURE;
03078     }
03079     else
03080     {
03081         if (!PnpGetLocalHandles(&BindingHandle, NULL))
03082             return CR_FAILURE;
03083     }
03084 
03085     RpcTryExcept
03086     {
03087         ret = PNP_GetGlobalState(BindingHandle, pulState, ulFlags);
03088     }
03089     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03090     {
03091         ret = RpcStatusToCmStatus(RpcExceptionCode());
03092     }
03093     RpcEndExcept;
03094 
03095     return ret;
03096 }
03097 
03098 
03099 /***********************************************************************
03100  * CM_Get_HW_Prof_FlagsA [SETUPAPI.@]
03101  */
03102 CONFIGRET WINAPI CM_Get_HW_Prof_FlagsA(
03103     DEVINSTID_A szDevInstName, ULONG ulHardwareProfile, PULONG pulValue,
03104     ULONG ulFlags)
03105 {
03106     TRACE("%s %lu %p %lx\n", szDevInstName,
03107           ulHardwareProfile, pulValue, ulFlags);
03108 
03109     return CM_Get_HW_Prof_Flags_ExA(szDevInstName, ulHardwareProfile,
03110                                     pulValue, ulFlags, NULL);
03111 }
03112 
03113 
03114 /***********************************************************************
03115  * CM_Get_HW_Prof_FlagsW [SETUPAPI.@]
03116  */
03117 CONFIGRET WINAPI CM_Get_HW_Prof_FlagsW(
03118     DEVINSTID_W szDevInstName, ULONG ulHardwareProfile, PULONG pulValue,
03119     ULONG ulFlags)
03120 {
03121     TRACE("%s %lu %p %lx\n", debugstr_w(szDevInstName),
03122           ulHardwareProfile, pulValue, ulFlags);
03123 
03124     return CM_Get_HW_Prof_Flags_ExW(szDevInstName, ulHardwareProfile,
03125                                     pulValue, ulFlags, NULL);
03126 }
03127 
03128 
03129 /***********************************************************************
03130  * CM_Get_HW_Prof_Flags_ExA [SETUPAPI.@]
03131  */
03132 CONFIGRET WINAPI CM_Get_HW_Prof_Flags_ExA(
03133     DEVINSTID_A szDevInstName, ULONG ulHardwareProfile, PULONG pulValue,
03134     ULONG ulFlags, HMACHINE hMachine)
03135 {
03136     DEVINSTID_W pszDevIdW = NULL;
03137     CONFIGRET ret = CR_SUCCESS;
03138 
03139     TRACE("%s %lu %p %lx %lx\n", szDevInstName,
03140           ulHardwareProfile, pulValue, ulFlags, hMachine);
03141 
03142     if (szDevInstName != NULL)
03143     {
03144        if (pSetupCaptureAndConvertAnsiArg(szDevInstName, &pszDevIdW))
03145          return CR_INVALID_DEVICE_ID;
03146     }
03147 
03148     ret = CM_Get_HW_Prof_Flags_ExW(pszDevIdW, ulHardwareProfile,
03149                                    pulValue, ulFlags, hMachine);
03150 
03151     if (pszDevIdW != NULL)
03152         MyFree(pszDevIdW);
03153 
03154     return ret;
03155 }
03156 
03157 
03158 /***********************************************************************
03159  * CM_Get_HW_Prof_Flags_ExW [SETUPAPI.@]
03160  */
03161 CONFIGRET WINAPI CM_Get_HW_Prof_Flags_ExW(
03162     DEVINSTID_W szDevInstName, ULONG ulHardwareProfile, PULONG pulValue,
03163     ULONG ulFlags, HMACHINE hMachine)
03164 {
03165     RPC_BINDING_HANDLE BindingHandle = NULL;
03166     CONFIGRET ret;
03167 
03168     FIXME("%s %lu %p %lx %lx\n", debugstr_w(szDevInstName),
03169           ulHardwareProfile, pulValue, ulFlags, hMachine);
03170 
03171     if ((szDevInstName == NULL) || (pulValue == NULL))
03172         return CR_INVALID_POINTER;
03173 
03174     if (ulFlags != 0)
03175         return CR_INVALID_FLAG;
03176 
03177     /* FIXME: Check whether szDevInstName is valid */
03178 
03179     if (hMachine != NULL)
03180     {
03181         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
03182         if (BindingHandle == NULL)
03183             return CR_FAILURE;
03184     }
03185     else
03186     {
03187         if (!PnpGetLocalHandles(&BindingHandle, NULL))
03188             return CR_FAILURE;
03189     }
03190 
03191     RpcTryExcept
03192     {
03193         ret = PNP_HwProfFlags(BindingHandle, PNP_GET_HWPROFFLAGS, szDevInstName,
03194                               ulHardwareProfile, pulValue, NULL, NULL, 0, 0);
03195     }
03196     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03197     {
03198         ret = RpcStatusToCmStatus(RpcExceptionCode());
03199     }
03200     RpcEndExcept;
03201 
03202     return ret;
03203 }
03204 
03205 
03206 /***********************************************************************
03207  * CM_Get_Hardware_Profile_InfoA [SETUPAPI.@]
03208  */
03209 CONFIGRET WINAPI CM_Get_Hardware_Profile_InfoA(
03210     ULONG ulIndex, PHWPROFILEINFO_A pHWProfileInfo, ULONG ulFlags)
03211 {
03212     TRACE("%lu %p %lx\n", ulIndex, pHWProfileInfo, ulFlags);
03213 
03214     return CM_Get_Hardware_Profile_Info_ExA(ulIndex, pHWProfileInfo,
03215                                             ulFlags, NULL);
03216 }
03217 
03218 
03219 /***********************************************************************
03220  * CM_Get_Hardware_Profile_InfoW [SETUPAPI.@]
03221  */
03222 CONFIGRET WINAPI CM_Get_Hardware_Profile_InfoW(
03223     ULONG ulIndex, PHWPROFILEINFO_W pHWProfileInfo, ULONG ulFlags)
03224 {
03225     TRACE("%lu %p %lx\n", ulIndex, pHWProfileInfo, ulFlags);
03226 
03227     return CM_Get_Hardware_Profile_Info_ExW(ulIndex, pHWProfileInfo,
03228                                             ulFlags, NULL);
03229 }
03230 
03231 
03232 /***********************************************************************
03233  * CM_Get_Hardware_Profile_Info_ExA [SETUPAPI.@]
03234  */
03235 CONFIGRET WINAPI CM_Get_Hardware_Profile_Info_ExA(
03236     ULONG ulIndex, PHWPROFILEINFO_A pHWProfileInfo, ULONG ulFlags,
03237     HMACHINE hMachine)
03238 {
03239     HWPROFILEINFO_W LocalProfileInfo;
03240     CONFIGRET ret;
03241 
03242     TRACE("%lu %p %lx %lx\n", ulIndex, pHWProfileInfo, ulFlags, hMachine);
03243 
03244     if (pHWProfileInfo == NULL)
03245         return CR_INVALID_POINTER;
03246 
03247     ret = CM_Get_Hardware_Profile_Info_ExW(ulIndex, &LocalProfileInfo,
03248                                            ulFlags, hMachine);
03249     if (ret == CR_SUCCESS)
03250     {
03251         pHWProfileInfo->HWPI_ulHWProfile = LocalProfileInfo.HWPI_ulHWProfile;
03252         pHWProfileInfo->HWPI_dwFlags = LocalProfileInfo.HWPI_dwFlags;
03253 
03254         if (WideCharToMultiByte(CP_ACP,
03255                                 0,
03256                                 LocalProfileInfo.HWPI_szFriendlyName,
03257                                 lstrlenW(LocalProfileInfo.HWPI_szFriendlyName) + 1,
03258                                 pHWProfileInfo->HWPI_szFriendlyName,
03259                                 MAX_PROFILE_LEN,
03260                                 NULL,
03261                                 NULL) == 0)
03262             ret = CR_FAILURE;
03263     }
03264 
03265     return ret;
03266 }
03267 
03268 
03269 /***********************************************************************
03270  * CM_Get_Hardware_Profile_Info_ExW [SETUPAPI.@]
03271  */
03272 CONFIGRET WINAPI CM_Get_Hardware_Profile_Info_ExW(
03273     ULONG ulIndex, PHWPROFILEINFO_W pHWProfileInfo, ULONG ulFlags,
03274     HMACHINE hMachine)
03275 {
03276     RPC_BINDING_HANDLE BindingHandle = NULL;
03277     CONFIGRET ret;
03278 
03279     TRACE("%lu %p %lx %lx\n", ulIndex, pHWProfileInfo, ulFlags, hMachine);
03280 
03281     if (pHWProfileInfo == NULL)
03282         return CR_INVALID_POINTER;
03283 
03284     if (ulFlags != 0)
03285         return CR_INVALID_FLAG;
03286 
03287     if (hMachine != NULL)
03288     {
03289         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
03290         if (BindingHandle == NULL)
03291             return CR_FAILURE;
03292     }
03293     else
03294     {
03295         if (!PnpGetLocalHandles(&BindingHandle, NULL))
03296             return CR_FAILURE;
03297     }
03298 
03299     RpcTryExcept
03300     {
03301         ret = PNP_GetHwProfInfo(BindingHandle, ulIndex, pHWProfileInfo,
03302                                 sizeof(HWPROFILEINFO_W), 0);
03303     }
03304     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03305     {
03306         ret = RpcStatusToCmStatus(RpcExceptionCode());
03307     }
03308     RpcEndExcept;
03309 
03310     return ret;
03311 }
03312 
03313 
03314 /***********************************************************************
03315  * CM_Get_Log_Conf_Priority [SETUPAPI.@]
03316  */
03317 CONFIGRET WINAPI CM_Get_Log_Conf_Priority(
03318     LOG_CONF lcLogConf, PPRIORITY pPriority, ULONG ulFlags)
03319 {
03320     TRACE("%p %p %lx\n", lcLogConf, pPriority, ulFlags);
03321     return CM_Get_Log_Conf_Priority_Ex(lcLogConf, pPriority, ulFlags, NULL);
03322 }
03323 
03324 
03325 /***********************************************************************
03326  * CM_Get_Log_Conf_Priority_Ex [SETUPAPI.@]
03327  */
03328 CONFIGRET WINAPI CM_Get_Log_Conf_Priority_Ex(
03329     LOG_CONF lcLogConf, PPRIORITY pPriority, ULONG ulFlags,
03330     HMACHINE hMachine)
03331 {
03332     RPC_BINDING_HANDLE BindingHandle = NULL;
03333     HSTRING_TABLE StringTable = NULL;
03334     PLOG_CONF_INFO pLogConfInfo;
03335     LPWSTR lpDevInst;
03336     CONFIGRET ret;
03337 
03338     FIXME("%p %p %lx %lx\n", lcLogConf, pPriority, ulFlags, hMachine);
03339 
03340     pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
03341     if (pLogConfInfo == NULL || pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
03342         return CR_INVALID_LOG_CONF;
03343 
03344     if (pPriority == NULL)
03345         return CR_INVALID_POINTER;
03346 
03347     if (ulFlags != 0)
03348         return CR_INVALID_FLAG;
03349 
03350     if (hMachine != NULL)
03351     {
03352         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
03353         if (BindingHandle == NULL)
03354             return CR_FAILURE;
03355 
03356         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
03357         if (StringTable == 0)
03358             return CR_FAILURE;
03359     }
03360     else
03361     {
03362         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
03363             return CR_FAILURE;
03364     }
03365 
03366     lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
03367     if (lpDevInst == NULL)
03368         return CR_INVALID_DEVNODE;
03369 
03370     RpcTryExcept
03371     {
03372         ret = PNP_GetLogConfPriority(BindingHandle,
03373                                      lpDevInst,
03374                                      pLogConfInfo->ulFlags,
03375                                      pLogConfInfo->ulTag,
03376                                      pPriority,
03377                                      0);
03378     }
03379     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03380     {
03381         ret = RpcStatusToCmStatus(RpcExceptionCode());
03382     }
03383     RpcEndExcept;
03384 
03385     return ret;
03386 }
03387 
03388 
03389 /***********************************************************************
03390  * CM_Get_Next_Log_Conf [SETUPAPI.@]
03391  */
03392 CONFIGRET WINAPI CM_Get_Next_Log_Conf(
03393     PLOG_CONF plcLogConf, LOG_CONF lcLogConf, ULONG ulFlags)
03394 {
03395     TRACE("%p %p %lx\n", plcLogConf, lcLogConf, ulFlags);
03396     return CM_Get_Next_Log_Conf_Ex(plcLogConf, lcLogConf, ulFlags, NULL);
03397 }
03398 
03399 
03400 /***********************************************************************
03401  * CM_Get_Next_Log_Conf_Ex [SETUPAPI.@]
03402  */
03403 CONFIGRET WINAPI CM_Get_Next_Log_Conf_Ex(
03404     PLOG_CONF plcLogConf, LOG_CONF lcLogConf, ULONG ulFlags,
03405     HMACHINE hMachine)
03406 {
03407     RPC_BINDING_HANDLE BindingHandle = NULL;
03408     HSTRING_TABLE StringTable = NULL;
03409     PLOG_CONF_INFO pLogConfInfo;
03410     PLOG_CONF_INFO pNewLogConfInfo;
03411     ULONG ulNewTag;
03412     LPWSTR lpDevInst;
03413     CONFIGRET ret;
03414 
03415     FIXME("%p %p %lx %lx\n", plcLogConf, lcLogConf, ulFlags, hMachine);
03416 
03417     if (plcLogConf)
03418         *plcLogConf = 0;
03419 
03420     pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
03421     if (pLogConfInfo == NULL || pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
03422         return CR_INVALID_LOG_CONF;
03423 
03424     if (ulFlags != 0)
03425         return CR_INVALID_FLAG;
03426 
03427     if (hMachine != NULL)
03428     {
03429         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
03430         if (BindingHandle == NULL)
03431             return CR_FAILURE;
03432 
03433         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
03434         if (StringTable == 0)
03435             return CR_FAILURE;
03436     }
03437     else
03438     {
03439         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
03440             return CR_FAILURE;
03441     }
03442 
03443     lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
03444     if (lpDevInst == NULL)
03445         return CR_INVALID_DEVNODE;
03446 
03447     RpcTryExcept
03448     {
03449         ret = PNP_GetNextLogConf(BindingHandle,
03450                                  lpDevInst,
03451                                  pLogConfInfo->ulFlags,
03452                                  pLogConfInfo->ulTag,
03453                                  &ulNewTag,
03454                                  0);
03455     }
03456     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03457     {
03458         ret = RpcStatusToCmStatus(RpcExceptionCode());
03459     }
03460     RpcEndExcept;
03461 
03462     if (ret != CR_SUCCESS)
03463         return ret;
03464 
03465     if (plcLogConf)
03466     {
03467         pNewLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
03468         if (pNewLogConfInfo == NULL)
03469             return CR_OUT_OF_MEMORY;
03470 
03471         pNewLogConfInfo->ulMagic = LOG_CONF_MAGIC;
03472         pNewLogConfInfo->dnDevInst = pLogConfInfo->dnDevInst;
03473         pNewLogConfInfo->ulFlags = pLogConfInfo->ulFlags;
03474         pNewLogConfInfo->ulTag = ulNewTag;
03475 
03476         *plcLogConf = (LOG_CONF)pNewLogConfInfo;
03477     }
03478 
03479     return CR_SUCCESS;
03480 }
03481 
03482 
03483 /***********************************************************************
03484  * CM_Get_Next_Re_Des [SETUPAPI.@]
03485  */
03486 CONFIGRET WINAPI CM_Get_Next_Res_Des(
03487     PRES_DES prdResDes, RES_DES rdResDes, RESOURCEID ForResource,
03488     PRESOURCEID pResourceID, ULONG ulFlags)
03489 {
03490     TRACE("%p %p %lu %p %lx\n", prdResDes, rdResDes, ForResource,
03491           pResourceID, ulFlags);
03492     return CM_Get_Next_Res_Des_Ex(prdResDes, rdResDes, ForResource,
03493                                   pResourceID, ulFlags, NULL);
03494 }
03495 
03496 
03497 /***********************************************************************
03498  * CM_Get_Next_Re_Des_Ex [SETUPAPI.@]
03499  */
03500 CONFIGRET WINAPI CM_Get_Next_Res_Des_Ex(
03501     PRES_DES prdResDes, RES_DES rdResDes, RESOURCEID ForResource,
03502     PRESOURCEID pResourceID, ULONG ulFlags, HMACHINE hMachine)
03503 {
03504     FIXME("%p %p %lu %p %lx %lx\n", prdResDes, rdResDes, ForResource,
03505           pResourceID, ulFlags, hMachine);
03506 
03507     return CR_CALL_NOT_IMPLEMENTED;
03508 }
03509 
03510 
03511 /***********************************************************************
03512  * CM_Get_Parent [SETUPAPI.@]
03513  */
03514 CONFIGRET WINAPI CM_Get_Parent(
03515     PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
03516 {
03517     TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
03518     return CM_Get_Parent_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
03519 }
03520 
03521 
03522 /***********************************************************************
03523  * CM_Get_Parent_Ex [SETUPAPI.@]
03524  */
03525 CONFIGRET WINAPI CM_Get_Parent_Ex(
03526     PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
03527 {
03528     WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
03529     RPC_BINDING_HANDLE BindingHandle = NULL;
03530     HSTRING_TABLE StringTable = NULL;
03531     LPWSTR lpDevInst;
03532     DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
03533     CONFIGRET ret;
03534 
03535     TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
03536 
03537     if (pdnDevInst == NULL)
03538         return CR_INVALID_POINTER;
03539 
03540     if (dnDevInst == 0)
03541         return CR_INVALID_DEVINST;
03542 
03543     if (ulFlags != 0)
03544         return CR_INVALID_FLAG;
03545 
03546     *pdnDevInst = -1;
03547 
03548     if (hMachine != NULL)
03549     {
03550         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
03551         if (BindingHandle == NULL)
03552             return CR_FAILURE;
03553 
03554         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
03555         if (StringTable == 0)
03556             return CR_FAILURE;
03557     }
03558     else
03559     {
03560         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
03561             return CR_FAILURE;
03562     }
03563 
03564     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
03565     if (lpDevInst == NULL)
03566         return CR_INVALID_DEVNODE;
03567 
03568     RpcTryExcept
03569     {
03570         ret = PNP_GetRelatedDeviceInstance(BindingHandle,
03571                                            PNP_GET_PARENT_DEVICE_INSTANCE,
03572                                            lpDevInst,
03573                                            szRelatedDevInst,
03574                                            &dwLength,
03575                                            0);
03576     }
03577     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03578     {
03579         ret = RpcStatusToCmStatus(RpcExceptionCode());
03580     }
03581     RpcEndExcept;
03582 
03583     if (ret != CR_SUCCESS)
03584         return ret;
03585 
03586     TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
03587 
03588     dwIndex = pSetupStringTableAddString(StringTable, szRelatedDevInst, 1);
03589     if (dwIndex == -1)
03590         return CR_FAILURE;
03591 
03592     *pdnDevInst = dwIndex;
03593 
03594     return CR_SUCCESS;
03595 }
03596 
03597 
03598 /***********************************************************************
03599  * CM_Get_Res_Des_Data [SETUPAPI.@]
03600  */
03601 CONFIGRET WINAPI CM_Get_Res_Des_Data(
03602     RES_DES rdResDes, PVOID Buffer, ULONG BufferLen, ULONG ulFlags)
03603 {
03604     TRACE("%p %p %l %lx\n", rdResDes, Buffer, BufferLen, ulFlags);
03605     return CM_Get_Res_Des_Data_Ex(rdResDes, Buffer, BufferLen, ulFlags, NULL);
03606 }
03607 
03608 
03609 /***********************************************************************
03610  * CM_Get_Res_Des_Data_Ex [SETUPAPI.@]
03611  */
03612 CONFIGRET WINAPI CM_Get_Res_Des_Data_Ex(
03613     RES_DES rdResDes, PVOID Buffer, ULONG BufferLen, ULONG ulFlags,
03614     HMACHINE hMachine)
03615 {
03616     FIXME("%p %p %l %lx %lx\n", rdResDes, Buffer, BufferLen, ulFlags, hMachine);
03617     return CR_CALL_NOT_IMPLEMENTED;
03618 }
03619 
03620 
03621 /***********************************************************************
03622  * CM_Get_Res_Des_Size [SETUPAPI.@]
03623  */
03624 CONFIGRET WINAPI CM_Get_Res_Des_Data_Size(
03625     PULONG pulSize, RES_DES rdResDes, ULONG ulFlags)
03626 {
03627     TRACE("%p %p %lx\n", pulSize, rdResDes, ulFlags);
03628     return CM_Get_Res_Des_Data_Size_Ex(pulSize, rdResDes, ulFlags, NULL);
03629 }
03630 
03631 
03632 /***********************************************************************
03633  * CM_Get_Res_Des_Size_Ex [SETUPAPI.@]
03634  */
03635 CONFIGRET WINAPI CM_Get_Res_Des_Data_Size_Ex(
03636     PULONG pulSize, RES_DES rdResDes, ULONG ulFlags, HMACHINE hMachine)
03637 {
03638     TRACE("%p %p %lx %lx\n", pulSize, rdResDes, ulFlags, hMachine);
03639     return CR_CALL_NOT_IMPLEMENTED;
03640 }
03641 
03642 
03643 /***********************************************************************
03644  * CM_Get_Sibling [SETUPAPI.@]
03645  */
03646 CONFIGRET WINAPI CM_Get_Sibling(
03647     PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
03648 {
03649     TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
03650     return CM_Get_Sibling_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
03651 }
03652 
03653 
03654 /***********************************************************************
03655  * CM_Get_Sibling_Ex [SETUPAPI.@]
03656  */
03657 CONFIGRET WINAPI CM_Get_Sibling_Ex(
03658     PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
03659 {
03660     WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
03661     RPC_BINDING_HANDLE BindingHandle = NULL;
03662     HSTRING_TABLE StringTable = NULL;
03663     LPWSTR lpDevInst;
03664     DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
03665     CONFIGRET ret;
03666 
03667     TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
03668 
03669     if (pdnDevInst == NULL)
03670         return CR_INVALID_POINTER;
03671 
03672     if (dnDevInst == 0)
03673         return CR_INVALID_DEVINST;
03674 
03675     if (ulFlags != 0)
03676         return CR_INVALID_FLAG;
03677 
03678     *pdnDevInst = -1;
03679 
03680     if (hMachine != NULL)
03681     {
03682         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
03683         if (BindingHandle == NULL)
03684             return CR_FAILURE;
03685 
03686         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
03687         if (StringTable == 0)
03688             return CR_FAILURE;
03689     }
03690     else
03691     {
03692         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
03693             return CR_FAILURE;
03694     }
03695 
03696     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
03697     if (lpDevInst == NULL)
03698         return CR_INVALID_DEVNODE;
03699 
03700     RpcTryExcept
03701     {
03702         ret = PNP_GetRelatedDeviceInstance(BindingHandle,
03703                                            PNP_GET_SIBLING_DEVICE_INSTANCE,
03704                                            lpDevInst,
03705                                            szRelatedDevInst,
03706                                            &dwLength,
03707                                            0);
03708     }
03709     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03710     {
03711         ret = RpcStatusToCmStatus(RpcExceptionCode());
03712     }
03713     RpcEndExcept;
03714 
03715     if (ret != CR_SUCCESS)
03716         return ret;
03717 
03718     TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
03719 
03720     dwIndex = pSetupStringTableAddString(StringTable, szRelatedDevInst, 1);
03721     if (dwIndex == -1)
03722         return CR_FAILURE;
03723 
03724     *pdnDevInst = dwIndex;
03725 
03726     return CR_SUCCESS;
03727 }
03728 
03729 
03730 /***********************************************************************
03731  * CM_Get_Version [SETUPAPI.@]
03732  */
03733 WORD WINAPI CM_Get_Version(VOID)
03734 {
03735     TRACE("\n");
03736     return CM_Get_Version_Ex(NULL);
03737 }
03738 
03739 
03740 /***********************************************************************
03741  * CM_Get_Version_Ex [SETUPAPI.@]
03742  */
03743 WORD WINAPI CM_Get_Version_Ex(HMACHINE hMachine)
03744 {
03745     RPC_BINDING_HANDLE BindingHandle = NULL;
03746     WORD Version = 0;
03747     CONFIGRET ret;
03748 
03749     TRACE("%lx\n", hMachine);
03750 
03751     if (hMachine != NULL)
03752     {
03753         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
03754         if (BindingHandle == NULL)
03755             return 0;
03756     }
03757     else
03758     {
03759         if (!PnpGetLocalHandles(&BindingHandle, NULL))
03760             return CR_FAILURE;
03761     }
03762 
03763     RpcTryExcept
03764     {
03765         ret = PNP_GetVersion(BindingHandle, &Version);
03766     }
03767     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03768     {
03769         ret = RpcStatusToCmStatus(RpcExceptionCode());
03770     }
03771     RpcEndExcept;
03772 
03773     if (ret != CR_SUCCESS)
03774         return 0;
03775 
03776     return Version;
03777 }
03778 
03779 
03780 /***********************************************************************
03781  * CM_Is_Dock_Station_Present [SETUPAPI.@]
03782  */
03783 CONFIGRET WINAPI CM_Is_Dock_Station_Present(
03784     PBOOL pbPresent)
03785 {
03786     TRACE("%p\n", pbPresent);
03787     return CM_Is_Dock_Station_Present_Ex(pbPresent, NULL);
03788 }
03789 
03790 
03791 /***********************************************************************
03792  * CM_Is_Dock_Station_Present_Ex [SETUPAPI.@]
03793  */
03794 CONFIGRET WINAPI CM_Is_Dock_Station_Present_Ex(
03795     PBOOL pbPresent, HMACHINE hMachine)
03796 {
03797     RPC_BINDING_HANDLE BindingHandle = NULL;
03798     CONFIGRET ret;
03799 
03800     TRACE("%p %lx\n", pbPresent, hMachine);
03801 
03802     if (pbPresent == NULL)
03803         return CR_INVALID_POINTER;
03804 
03805     *pbPresent = FALSE;
03806 
03807     if (hMachine != NULL)
03808     {
03809         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
03810         if (BindingHandle == NULL)
03811             return CR_FAILURE;
03812     }
03813     else
03814     {
03815         if (!PnpGetLocalHandles(&BindingHandle, NULL))
03816             return CR_FAILURE;
03817     }
03818 
03819     RpcTryExcept
03820     {
03821         ret = PNP_IsDockStationPresent(BindingHandle,
03822                                        pbPresent);
03823     }
03824     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03825     {
03826         ret = RpcStatusToCmStatus(RpcExceptionCode());
03827     }
03828     RpcEndExcept;
03829 
03830     return ret;
03831 }
03832 
03833 
03834 /***********************************************************************
03835  * CM_Is_Version_Available_Ex [SETUPAPI.@]
03836  */
03837 BOOL WINAPI CM_Is_Version_Available(
03838      WORD wVersion)
03839 {
03840     TRACE("%hu\n", wVersion);
03841     return CM_Is_Version_Available_Ex(wVersion, NULL);
03842 }
03843 
03844 
03845 /***********************************************************************
03846  * CM_Is_Version_Available_Ex [SETUPAPI.@]
03847  */
03848 BOOL WINAPI CM_Is_Version_Available_Ex(
03849     WORD wVersion, HMACHINE hMachine)
03850 {
03851     RPC_BINDING_HANDLE BindingHandle = NULL;
03852     WORD wServerVersion;
03853     CONFIGRET ret;
03854 
03855     TRACE("%hu %lx\n", wVersion, hMachine);
03856 
03857     if (wVersion <= 0x400)
03858         return TRUE;
03859 
03860     if (hMachine != NULL)
03861     {
03862         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
03863         if (BindingHandle == NULL)
03864             return FALSE;
03865     }
03866     else
03867     {
03868         if (!PnpGetLocalHandles(&BindingHandle, NULL))
03869             return FALSE;
03870     }
03871 
03872     RpcTryExcept
03873     {
03874         ret = PNP_GetVersion(BindingHandle, &wServerVersion);
03875     }
03876     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03877     {
03878         ret = RpcStatusToCmStatus(RpcExceptionCode());
03879     }
03880     RpcEndExcept;
03881 
03882     if (ret != CR_SUCCESS)
03883         return FALSE;
03884 
03885     return (wServerVersion >= wVersion);
03886 }
03887 
03888 
03889 /***********************************************************************
03890  * CM_Locate_DevNodeA [SETUPAPI.@]
03891  */
03892 CONFIGRET WINAPI CM_Locate_DevNodeA(
03893     PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags)
03894 {
03895     TRACE("%p %s %lu\n", pdnDevInst, pDeviceID, ulFlags);
03896     return CM_Locate_DevNode_ExA(pdnDevInst, pDeviceID, ulFlags, NULL);
03897 }
03898 
03899 
03900 /***********************************************************************
03901  * CM_Locate_DevNodeW [SETUPAPI.@]
03902  */
03903 CONFIGRET WINAPI CM_Locate_DevNodeW(
03904     PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags)
03905 {
03906     TRACE("%p %s %lu\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags);
03907     return CM_Locate_DevNode_ExW(pdnDevInst, pDeviceID, ulFlags, NULL);
03908 }
03909 
03910 
03911 /***********************************************************************
03912  * CM_Locate_DevNode_ExA [SETUPAPI.@]
03913  */
03914 CONFIGRET WINAPI CM_Locate_DevNode_ExA(
03915     PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags, HMACHINE hMachine)
03916 {
03917     DEVINSTID_W pDevIdW = NULL;
03918     CONFIGRET ret = CR_SUCCESS;
03919 
03920     TRACE("%p %s %lu %lx\n", pdnDevInst, pDeviceID, ulFlags, hMachine);
03921 
03922     if (pDeviceID != NULL)
03923     {
03924        if (pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDevIdW))
03925          return CR_INVALID_DEVICE_ID;
03926     }
03927 
03928     ret = CM_Locate_DevNode_ExW(pdnDevInst, pDevIdW, ulFlags, hMachine);
03929 
03930     if (pDevIdW != NULL)
03931         MyFree(pDevIdW);
03932 
03933     return ret;
03934 }
03935 
03936 
03937 /***********************************************************************
03938  * CM_Locate_DevNode_ExW [SETUPAPI.@]
03939  */
03940 CONFIGRET WINAPI CM_Locate_DevNode_ExW(
03941     PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags, HMACHINE hMachine)
03942 {
03943     WCHAR DeviceIdBuffer[MAX_DEVICE_ID_LEN];
03944     RPC_BINDING_HANDLE BindingHandle = NULL;
03945     HSTRING_TABLE StringTable = NULL;
03946     CONFIGRET ret = CR_SUCCESS;
03947 
03948     TRACE("%p %s %lu %lx\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags, hMachine);
03949 
03950     if (pdnDevInst == NULL)
03951         return CR_INVALID_POINTER;
03952 
03953     if (ulFlags & ~CM_LOCATE_DEVNODE_BITS)
03954         return CR_INVALID_FLAG;
03955 
03956     if (hMachine != NULL)
03957     {
03958         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
03959         if (BindingHandle == NULL)
03960             return CR_FAILURE;
03961 
03962         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
03963         if (StringTable == 0)
03964             return CR_FAILURE;
03965     }
03966     else
03967     {
03968         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
03969             return CR_FAILURE;
03970     }
03971 
03972     if (pDeviceID != NULL && lstrlenW(pDeviceID) != 0)
03973     {
03974         lstrcpyW(DeviceIdBuffer, pDeviceID);
03975     }
03976     else
03977     {
03978         RpcTryExcept
03979         {
03980             /* Get the root device ID */
03981             ret = PNP_GetRootDeviceInstance(BindingHandle,
03982                                             DeviceIdBuffer,
03983                                             MAX_DEVICE_ID_LEN);
03984         }
03985         RpcExcept(EXCEPTION_EXECUTE_HANDLER)
03986         {
03987             ret = RpcStatusToCmStatus(RpcExceptionCode());
03988         }
03989         RpcEndExcept;
03990 
03991         if (ret != CR_SUCCESS)
03992             return CR_FAILURE;
03993     }
03994     TRACE("DeviceIdBuffer: %s\n", debugstr_w(DeviceIdBuffer));
03995 
03996     RpcTryExcept
03997     {
03998         /* Validate the device ID */
03999         ret = PNP_ValidateDeviceInstance(BindingHandle,
04000                                          DeviceIdBuffer,
04001                                          ulFlags);
04002     }
04003     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
04004     {
04005         ret = RpcStatusToCmStatus(RpcExceptionCode());
04006     }
04007     RpcEndExcept;
04008 
04009     if (ret == CR_SUCCESS)
04010     {
04011         *pdnDevInst = pSetupStringTableAddString(StringTable, DeviceIdBuffer, 1);
04012         if (*pdnDevInst == -1)
04013             ret = CR_FAILURE;
04014     }
04015 
04016     return ret;
04017 }
04018 
04019 
04020 /***********************************************************************
04021  * CM_Modify_Res_Des [SETUPAPI.@]
04022  */
04023 CONFIGRET WINAPI CM_Modify_Res_Des(
04024     PRES_DES prdResDes, RES_DES rdResDes, RESOURCEID ResourceID,
04025     PCVOID ResourceData, ULONG ResourceLen, ULONG ulFlags)
04026 {
04027     TRACE("%p %p %lx %p %lu %lx", prdResDes, rdResDes, ResourceID, ResourceData,
04028           ResourceLen, ulFlags);
04029     return CM_Modify_Res_Des_Ex(prdResDes, rdResDes, ResourceID, ResourceData,
04030                                 ResourceLen, ulFlags, NULL);
04031 }
04032 
04033 
04034 /***********************************************************************
04035  * CM_Modify_Res_Des_Ex [SETUPAPI.@]
04036  */
04037 CONFIGRET WINAPI CM_Modify_Res_Des_Ex(
04038     PRES_DES prdResDes, RES_DES rdResDes, RESOURCEID ResourceID, PCVOID ResourceData,
04039     ULONG ResourceLen, ULONG ulFlags, HMACHINE hMachine)
04040 {
04041     FIXME("%p %p %lx %p %lu %lx %lx", prdResDes, rdResDes, ResourceID, ResourceData,
04042           ResourceLen, ulFlags, hMachine);
04043     return CR_CALL_NOT_IMPLEMENTED;
04044 }
04045 
04046 
04047 /***********************************************************************
04048  * CM_Move_DevNode [SETUPAPI.@]
04049  */
04050 CONFIGRET WINAPI CM_Move_DevNode(
04051     DEVINST dnFromDevInst, DEVINST dnToDevInst, ULONG ulFlags)
04052 {
04053     TRACE("%lx %lx %lx\n", dnFromDevInst, dnToDevInst, ulFlags);
04054     return CM_Move_DevNode_Ex(dnFromDevInst, dnToDevInst, ulFlags, NULL);
04055 }
04056 
04057 
04058 /***********************************************************************
04059  * CM_Move_DevNode_Ex [SETUPAPI.@]
04060  */
04061 CONFIGRET WINAPI CM_Move_DevNode_Ex(
04062     DEVINST dnFromDevInst, DEVINST dnToDevInst, ULONG ulFlags,
04063     HMACHINE hMachine)
04064 {
04065     RPC_BINDING_HANDLE BindingHandle = NULL;
04066     HSTRING_TABLE StringTable = NULL;
04067     LPWSTR lpFromDevInst;
04068     LPWSTR lpToDevInst;
04069     CONFIGRET ret;
04070 
04071     FIXME("%lx %lx %lx %lx\n",
04072           dnFromDevInst, dnToDevInst, ulFlags, hMachine);
04073 
04074     if (!pSetupIsUserAdmin())
04075         return CR_ACCESS_DENIED;
04076 
04077     if (dnFromDevInst == 0 || dnToDevInst == 0)
04078         return CR_INVALID_DEVNODE;
04079 
04080     if (ulFlags != 0)
04081         return CR_INVALID_FLAG;
04082 
04083     if (hMachine != NULL)
04084     {
04085         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
04086         if (BindingHandle == NULL)
04087             return CR_FAILURE;
04088 
04089         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
04090         if (StringTable == 0)
04091             return CR_FAILURE;
04092     }
04093     else
04094     {
04095         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
04096             return CR_FAILURE;
04097     }
04098 
04099     lpFromDevInst = pSetupStringTableStringFromId(StringTable, dnFromDevInst);
04100     if (lpFromDevInst == NULL)
04101         return CR_INVALID_DEVNODE;
04102 
04103     lpToDevInst = pSetupStringTableStringFromId(StringTable, dnToDevInst);
04104     if (lpToDevInst == NULL)
04105         return CR_INVALID_DEVNODE;
04106 
04107     RpcTryExcept
04108     {
04109         ret = PNP_DeviceInstanceAction(BindingHandle,
04110                                        PNP_DEVINST_MOVE,
04111                                        ulFlags,
04112                                        lpFromDevInst,
04113                                        lpToDevInst);
04114     }
04115     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
04116     {
04117         ret = RpcStatusToCmStatus(RpcExceptionCode());
04118     }
04119     RpcEndExcept;
04120 
04121     return ret;
04122 }
04123 
04124 
04125 /***********************************************************************
04126  * CM_Open_Class_KeyA [SETUPAPI.@]
04127  */
04128 CONFIGRET WINAPI CM_Open_Class_KeyA(
04129     LPGUID pClassGuid, LPCSTR pszClassName, REGSAM samDesired,
04130     REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags)
04131 {
04132     TRACE("%p %s %lx %lx %p %lx\n",
04133           debugstr_guid(pClassGuid), pszClassName,
04134           samDesired, Disposition, phkClass, ulFlags);
04135 
04136     return CM_Open_Class_Key_ExA(pClassGuid, pszClassName, samDesired,
04137                                  Disposition, phkClass, ulFlags, NULL);
04138 }
04139 
04140 
04141 /***********************************************************************
04142  * CM_Open_Class_KeyW [SETUPAPI.@]
04143  */
04144 CONFIGRET WINAPI CM_Open_Class_KeyW(
04145     LPGUID pClassGuid, LPCWSTR pszClassName, REGSAM samDesired,
04146     REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags)
04147 {
04148     TRACE("%p %s %lx %lx %p %lx\n",
04149           debugstr_guid(pClassGuid), debugstr_w(pszClassName),
04150           samDesired, Disposition, phkClass, ulFlags);
04151 
04152     return CM_Open_Class_Key_ExW(pClassGuid, pszClassName, samDesired,
04153                                  Disposition, phkClass, ulFlags, NULL);
04154 }
04155 
04156 
04157 /***********************************************************************
04158  * CM_Open_Class_Key_ExA [SETUPAPI.@]
04159  */
04160 CONFIGRET WINAPI CM_Open_Class_Key_ExA(
04161     LPGUID pClassGuid, LPCSTR pszClassName, REGSAM samDesired,
04162     REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags,
04163     HMACHINE hMachine)
04164 {
04165     LPWSTR pszClassNameW = NULL;
04166     CONFIGRET ret;
04167 
04168     TRACE("%p %s %lx %lx %p %lx %lx\n",
04169           debugstr_guid(pClassGuid), pszClassName,
04170           samDesired, Disposition, phkClass, ulFlags, hMachine);
04171 
04172     if (pszClassName != NULL)
04173     {
04174        if (pSetupCaptureAndConvertAnsiArg(pszClassName, &pszClassNameW))
04175          return CR_INVALID_DATA;
04176     }
04177 
04178     ret = CM_Open_Class_Key_ExW(pClassGuid, pszClassNameW, samDesired,
04179                                 Disposition, phkClass, ulFlags, hMachine);
04180 
04181     if (pszClassNameW != NULL)
04182         MyFree(pszClassNameW);
04183 
04184     return ret;
04185 }
04186 
04187 
04188 /***********************************************************************
04189  * CM_Open_Class_Key_ExW [SETUPAPI.@]
04190  */
04191 CONFIGRET WINAPI CM_Open_Class_Key_ExW(
04192     LPGUID pClassGuid, LPCWSTR pszClassName, REGSAM samDesired,
04193     REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags,
04194     HMACHINE hMachine)
04195 {
04196     WCHAR szKeyName[MAX_PATH];
04197     LPWSTR lpGuidString;
04198     DWORD dwDisposition;
04199     DWORD dwError;
04200     HKEY hKey;
04201 
04202     TRACE("%p %s %lx %lx %p %lx %lx\n",
04203           debugstr_guid(pClassGuid), debugstr_w(pszClassName),
04204           samDesired, Disposition, phkClass, ulFlags, hMachine);
04205 
04206     /* Check Disposition and ulFlags */
04207     if ((Disposition & ~RegDisposition_Bits) ||
04208         (ulFlags & ~CM_OPEN_CLASS_KEY_BITS))
04209         return CR_INVALID_FLAG;
04210 
04211     /* Check phkClass */
04212     if (phkClass == NULL)
04213         return CR_INVALID_POINTER;
04214 
04215     *phkClass = NULL;
04216 
04217     if (ulFlags == CM_OPEN_CLASS_KEY_INTERFACE &&
04218         pszClassName != NULL)
04219         return CR_INVALID_DATA;
04220 
04221     if (hMachine == NULL)
04222     {
04223         hKey = HKEY_LOCAL_MACHINE;
04224     }
04225     else
04226     {
04227        if (RegConnectRegistryW(((PMACHINE_INFO)hMachine)->szMachineName,
04228                                HKEY_LOCAL_MACHINE, &hKey))
04229            return CR_REGISTRY_ERROR;
04230     }
04231 
04232     if (ulFlags & CM_OPEN_CLASS_KEY_INTERFACE)
04233     {
04234         lstrcpyW(szKeyName, DeviceClasses);
04235     }
04236     else
04237     {
04238         lstrcpyW(szKeyName, ControlClass);
04239     }
04240 
04241     if (pClassGuid != NULL)
04242     {
04243         if (UuidToStringW((UUID*)pClassGuid, &lpGuidString) != RPC_S_OK)
04244         {
04245             RegCloseKey(hKey);
04246             return CR_INVALID_DATA;
04247         }
04248 
04249         lstrcatW(szKeyName, Backslash);
04250         lstrcatW(szKeyName, lpGuidString);
04251     }
04252 
04253     if (Disposition == RegDisposition_OpenAlways)
04254     {
04255         dwError = RegCreateKeyExW(hKey, szKeyName, 0, NULL, 0, samDesired,
04256                                   NULL, phkClass, &dwDisposition);
04257     }
04258     else
04259     {
04260         dwError = RegOpenKeyExW(hKey, szKeyName, 0, samDesired, phkClass);
04261     }
04262 
04263     RegCloseKey(hKey);
04264 
04265     if (pClassGuid != NULL)
04266         RpcStringFreeW(&lpGuidString);
04267 
04268     if (dwError != ERROR_SUCCESS)
04269     {
04270         *phkClass = NULL;
04271         return CR_NO_SUCH_REGISTRY_KEY;
04272     }
04273 
04274     if (pszClassName != NULL)
04275     {
04276         RegSetValueExW(*phkClass, Class, 0, REG_SZ, (LPBYTE)pszClassName,
04277                        (lstrlenW(pszClassName) + 1) * sizeof(WCHAR));
04278     }
04279 
04280     return CR_SUCCESS;
04281 }
04282 
04283 
04284 /***********************************************************************
04285  * CM_Open_DevNode_Key [SETUPAPI.@]
04286  */
04287 CONFIGRET WINAPI CM_Open_DevNode_Key(
04288     DEVINST dnDevNode, REGSAM samDesired, ULONG ulHardwareProfile,
04289     REGDISPOSITION Disposition, PHKEY phkDevice, ULONG ulFlags)
04290 {
04291     TRACE("%lx %lx %lu %lx %p %lx\n", dnDevNode, samDesired,
04292           ulHardwareProfile, Disposition, phkDevice, ulFlags);
04293     return CM_Open_DevNode_Key_Ex(dnDevNode, samDesired, ulHardwareProfile,
04294                                   Disposition, phkDevice, ulFlags, NULL);
04295 }
04296 
04297 
04298 /***********************************************************************
04299  * CM_Open_DevNode_Key_Ex [SETUPAPI.@]
04300  */
04301 CONFIGRET WINAPI CM_Open_DevNode_Key_Ex(
04302     DEVINST dnDevNode, REGSAM samDesired, ULONG ulHardwareProfile,
04303     REGDISPOSITION Disposition, PHKEY phkDevice, ULONG ulFlags,
04304     HMACHINE hMachine)
04305 {
04306     FIXME("%lx %lx %lu %lx %p %lx %lx\n", dnDevNode, samDesired,
04307           ulHardwareProfile, Disposition, phkDevice, ulFlags, hMachine);
04308 
04309     return CR_CALL_NOT_IMPLEMENTED;
04310 }
04311 
04312 
04313 /***********************************************************************
04314  * CM_Query_And_Remove_SubTreeA [SETUPAPI.@]
04315  */
04316 CONFIGRET WINAPI CM_Query_And_Remove_SubTreeA(
04317     DEVINST dnAncestor, PPNP_VETO_TYPE pVetoType, LPSTR pszVetoName,
04318     ULONG ulNameLength, ULONG ulFlags)
04319 {
04320     TRACE("%lx %p %s %lu %lx\n", dnAncestor, pVetoType, pszVetoName,
04321           ulNameLength, ulFlags);
04322 
04323     return CM_Query_And_Remove_SubTree_ExA(dnAncestor, pVetoType, pszVetoName,
04324                                            ulNameLength, ulFlags, NULL);
04325 }
04326 
04327 
04328 /***********************************************************************
04329  * CM_Query_And_Remove_SubTreeW [SETUPAPI.@]
04330  */
04331 CONFIGRET WINAPI CM_Query_And_Remove_SubTreeW(
04332     DEVINST dnAncestor, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName,
04333     ULONG ulNameLength, ULONG ulFlags)
04334 {
04335     TRACE("%lx %p %s %lu %lx\n", dnAncestor, pVetoType,
04336           debugstr_w(pszVetoName), ulNameLength, ulFlags);
04337 
04338     return CM_Query_And_Remove_SubTree_ExW(dnAncestor, pVetoType, pszVetoName,
04339                                            ulNameLength, ulFlags, NULL);
04340 }
04341 
04342 
04343 /***********************************************************************
04344  * CM_Query_And_Remove_SubTree_ExA [SETUPAPI.@]
04345  */
04346 CONFIGRET WINAPI CM_Query_And_Remove_SubTree_ExA(
04347     DEVINST dnAncestor, PPNP_VETO_TYPE pVetoType, LPSTR pszVetoName,
04348     ULONG ulNameLength, ULONG ulFlags, HMACHINE hMachine)
04349 {
04350     LPWSTR lpLocalVetoName;
04351     CONFIGRET ret;
04352 
04353     TRACE("%lx %p %s %lu %lx %lx\n", dnAncestor, pVetoType, pszVetoName,
04354           ulNameLength, ulFlags, hMachine);
04355 
04356     if (pszVetoName == NULL && ulNameLength == 0)
04357         return CR_INVALID_POINTER;
04358 
04359     lpLocalVetoName = HeapAlloc(GetProcessHeap(), 0, ulNameLength * sizeof(WCHAR));
04360     if (lpLocalVetoName == NULL)
04361         return CR_OUT_OF_MEMORY;
04362 
04363     ret = CM_Query_And_Remove_SubTree_ExW(dnAncestor, pVetoType, lpLocalVetoName,
04364                                           ulNameLength, ulFlags, hMachine);
04365     if (ret == CR_REMOVE_VETOED)
04366     {
04367         if (WideCharToMultiByte(CP_ACP,
04368                                 0,
04369                                 lpLocalVetoName,
04370                                 ulNameLength,
04371                                 pszVetoName,
04372                                 ulNameLength,
04373                                 NULL,
04374                                 NULL) == 0)
04375             ret = CR_FAILURE;
04376     }
04377 
04378     HeapFree(GetProcessHeap(), 0, lpLocalVetoName);
04379 
04380     return ret;
04381 }
04382 
04383 
04384 /***********************************************************************
04385  * CM_Query_And_Remove_SubTree_ExW [SETUPAPI.@]
04386  */
04387 CONFIGRET WINAPI CM_Query_And_Remove_SubTree_ExW(
04388     DEVINST dnAncestor, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName,
04389     ULONG ulNameLength, ULONG ulFlags, HMACHINE hMachine)
04390 {
04391     RPC_BINDING_HANDLE BindingHandle = NULL;
04392     HSTRING_TABLE StringTable = NULL;
04393     LPWSTR lpDevInst;
04394     CONFIGRET ret;
04395 
04396     TRACE("%lx %p %s %lu %lx %lx\n", dnAncestor, pVetoType,
04397           debugstr_w(pszVetoName), ulNameLength, ulFlags, hMachine);
04398 
04399     if (dnAncestor == 0)
04400         return CR_INVALID_DEVNODE;
04401 
04402     if (ulFlags & ~CM_REMOVE_BITS)
04403         return CR_INVALID_FLAG;
04404 
04405     if (pszVetoName == NULL && ulNameLength == 0)
04406         return CR_INVALID_POINTER;
04407 
04408     if (hMachine != NULL)
04409     {
04410         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
04411         if (BindingHandle == NULL)
04412             return CR_FAILURE;
04413 
04414         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
04415         if (StringTable == 0)
04416             return CR_FAILURE;
04417     }
04418     else
04419     {
04420         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
04421             return CR_FAILURE;
04422     }
04423 
04424     lpDevInst = pSetupStringTableStringFromId(StringTable, dnAncestor);
04425     if (lpDevInst == NULL)
04426         return CR_INVALID_DEVNODE;
04427 
04428     RpcTryExcept
04429     {
04430         ret = PNP_QueryRemove(BindingHandle,
04431                               lpDevInst,
04432                               pVetoType,
04433                               pszVetoName,
04434                               ulNameLength,
04435                               ulFlags);
04436     }
04437     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
04438     {
04439         ret = RpcStatusToCmStatus(RpcExceptionCode());
04440     }
04441     RpcEndExcept;
04442 
04443     return ret;
04444 }
04445 
04446 
04447 /***********************************************************************
04448  * CM_Query_Arbitrator_Free_Data [SETUPAPI.@]
04449  */
04450 CONFIGRET WINAPI CM_Query_Arbitrator_Free_Data(
04451     PVOID pData, ULONG DataLen, DEVINST dnDevInst, RESOURCEID ResourceID,
04452     ULONG ulFlags)
04453 {
04454     TRACE("%p %lu %lx %lu 0x%08lx\n", pData, DataLen, dnDevInst,
04455           ResourceID, ulFlags);
04456 
04457     return CM_Query_Arbitrator_Free_Data_Ex(pData, DataLen, dnDevInst,
04458                                             ResourceID, ulFlags, NULL);
04459 }
04460 
04461 
04462 /***********************************************************************
04463  * CM_Query_Arbitrator_Free_Data_Ex [SETUPAPI.@]
04464  */
04465 CONFIGRET WINAPI CM_Query_Arbitrator_Free_Data_Ex(
04466   OUT PVOID pData,
04467   IN ULONG DataLen,
04468   IN DEVINST dnDevInst,
04469   IN RESOURCEID ResourceID,
04470   IN ULONG ulFlags,
04471   IN HMACHINE hMachine)
04472 {
04473     RPC_BINDING_HANDLE BindingHandle = NULL;
04474     HSTRING_TABLE StringTable = NULL;
04475     LPWSTR lpDevInst;
04476     CONFIGRET ret;
04477 
04478     TRACE("%p %lu %lx %lu 0x%08lx %p\n", pData, DataLen, dnDevInst,
04479           ResourceID, ulFlags, hMachine);
04480 
04481     if (pData == NULL || DataLen == 0)
04482         return CR_INVALID_POINTER;
04483 
04484     if (dnDevInst == 0)
04485         return CR_INVALID_DEVINST;
04486 
04487     if (ulFlags & ~CM_QUERY_ARBITRATOR_BITS)
04488         return CR_INVALID_FLAG;
04489 
04490     if (hMachine != NULL)
04491     {
04492         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
04493         if (BindingHandle == NULL)
04494             return CR_FAILURE;
04495 
04496         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
04497         if (StringTable == 0)
04498             return CR_FAILURE;
04499     }
04500     else
04501     {
04502         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
04503             return CR_FAILURE;
04504     }
04505 
04506     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
04507     if (lpDevInst == NULL)
04508         return CR_INVALID_DEVNODE;
04509 
04510     RpcTryExcept
04511     {
04512         ret = PNP_QueryArbitratorFreeData(BindingHandle,
04513                                           pData,
04514                                           DataLen,
04515                                           lpDevInst,
04516                                           ResourceID,
04517                                           ulFlags);
04518     }
04519     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
04520     {
04521         ret = RpcStatusToCmStatus(RpcExceptionCode());
04522     }
04523     RpcEndExcept;
04524 
04525     return ret;
04526 }
04527 
04528 
04529 /***********************************************************************
04530  * CM_Query_Arbitrator_Free_Size [SETUPAPI.@]
04531  */
04532 CONFIGRET WINAPI CM_Query_Arbitrator_Free_Size(
04533     PULONG pulSize, DEVINST dnDevInst, RESOURCEID ResourceID, ULONG ulFlags)
04534 {
04535     TRACE("%p %lu %lx 0x%08lx\n", pulSize, dnDevInst,ResourceID, ulFlags);
04536 
04537     return CM_Query_Arbitrator_Free_Size_Ex(pulSize, dnDevInst, ResourceID,
04538                                             ulFlags, NULL);
04539 }
04540 
04541 
04542 /***********************************************************************
04543  * CM_Query_Arbitrator_Free_Size_Ex [SETUPAPI.@]
04544  */
04545 CONFIGRET WINAPI CM_Query_Arbitrator_Free_Size_Ex(
04546       PULONG pulSize, DEVINST dnDevInst, RESOURCEID ResourceID,
04547       ULONG ulFlags, HMACHINE hMachine)
04548 {
04549     RPC_BINDING_HANDLE BindingHandle = NULL;
04550     HSTRING_TABLE StringTable = NULL;
04551     LPWSTR lpDevInst;
04552     CONFIGRET ret;
04553 
04554     TRACE("%p %lu %lx 0x%08lx %p\n", pulSize, dnDevInst,ResourceID, ulFlags,
04555           hMachine);
04556 
04557     if (pulSize == NULL)
04558         return CR_INVALID_POINTER;
04559 
04560     if (dnDevInst == 0)
04561         return CR_INVALID_DEVINST;
04562 
04563     if (ulFlags & ~CM_QUERY_ARBITRATOR_BITS)
04564         return CR_INVALID_FLAG;
04565 
04566     if (hMachine != NULL)
04567     {
04568         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
04569         if (BindingHandle == NULL)
04570             return CR_FAILURE;
04571 
04572         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
04573         if (StringTable == 0)
04574             return CR_FAILURE;
04575     }
04576     else
04577     {
04578         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
04579             return CR_FAILURE;
04580     }
04581 
04582     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
04583     if (lpDevInst == NULL)
04584         return CR_INVALID_DEVNODE;
04585 
04586     RpcTryExcept
04587     {
04588         ret = PNP_QueryArbitratorFreeSize(BindingHandle,
04589                                           pulSize,
04590                                           lpDevInst,
04591                                           ResourceID,
04592                                           ulFlags);
04593     }
04594     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
04595     {
04596         ret = RpcStatusToCmStatus(RpcExceptionCode());
04597     }
04598     RpcEndExcept;
04599 
04600     return ret;
04601 }
04602 
04603 
04604 /***********************************************************************
04605  * CM_Query_Remove_SubTree [SETUPAPI.@]
04606  *
04607  * This function is obsolete in Windows XP and above.
04608  */
04609 CONFIGRET WINAPI CM_Query_Remove_SubTree(
04610     DEVINST dnAncestor, ULONG ulFlags)
04611 {
04612     TRACE("%lx %lx\n", dnAncestor, ulFlags);
04613     return CR_CALL_NOT_IMPLEMENTED;
04614 }
04615 
04616 
04617 /***********************************************************************
04618  * CM_Query_Remove_SubTree_Ex [SETUPAPI.@]
04619  *
04620  * This function is obsolete in Windows XP and above.
04621  */
04622 CONFIGRET WINAPI CM_Query_Remove_SubTree_Ex(
04623     DEVINST dnAncestor, ULONG ulFlags, HMACHINE hMachine)
04624 {
04625     TRACE("%lx %lx %lx\n", dnAncestor, ulFlags, hMachine);
04626     return CR_CALL_NOT_IMPLEMENTED;
04627 }
04628 
04629 
04630 /***********************************************************************
04631  * CM_Reenumerate_DevNode [SETUPAPI.@]
04632  */
04633 CONFIGRET WINAPI CM_Reenumerate_DevNode(
04634     DEVINST dnDevInst, ULONG ulFlags)
04635 {
04636     TRACE("%lx %lx\n", dnDevInst, ulFlags);
04637     return CM_Reenumerate_DevNode_Ex(dnDevInst, ulFlags, NULL);
04638 }
04639 
04640 
04641 /***********************************************************************
04642  * CM_Reenumerate_DevNode_Ex [SETUPAPI.@]
04643  */
04644 CONFIGRET WINAPI
04645 CM_Reenumerate_DevNode_Ex(
04646     DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
04647 {
04648     RPC_BINDING_HANDLE BindingHandle = NULL;
04649     HSTRING_TABLE StringTable = NULL;
04650     LPWSTR lpDevInst;
04651     CONFIGRET ret;
04652 
04653     FIXME("%lx %lx %lx\n", dnDevInst, ulFlags, hMachine);
04654 
04655     if (dnDevInst == 0)
04656         return CR_INVALID_DEVNODE;
04657 
04658     if (ulFlags & ~CM_REENUMERATE_BITS)
04659         return CR_INVALID_FLAG;
04660 
04661     if (hMachine != NULL)
04662     {
04663         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
04664         if (BindingHandle == NULL)
04665             return CR_FAILURE;
04666 
04667         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
04668         if (StringTable == 0)
04669             return CR_FAILURE;
04670     }
04671     else
04672     {
04673         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
04674             return CR_FAILURE;
04675     }
04676 
04677     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
04678     if (lpDevInst == NULL)
04679         return CR_INVALID_DEVNODE;
04680 
04681     RpcTryExcept
04682     {
04683         ret = PNP_DeviceInstanceAction(BindingHandle,
04684                                        PNP_DEVINST_REENUMERATE,
04685                                        ulFlags,
04686                                        lpDevInst,
04687                                        NULL);
04688     }
04689     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
04690     {
04691         ret = RpcStatusToCmStatus(RpcExceptionCode());
04692     }
04693     RpcEndExcept;
04694 
04695     return ret;
04696 }
04697 
04698 
04699 /***********************************************************************
04700  * CM_Register_Device_InterfaceA [SETUPAPI.@]
04701  */
04702 CONFIGRET WINAPI CM_Register_Device_InterfaceA(
04703     DEVINST dnDevInst, LPGUID InterfaceClassGuid, LPCSTR pszReference,
04704     LPSTR pszDeviceInterface, PULONG pulLength, ULONG ulFlags)
04705 {
04706     TRACE("%lx %s %s %p %p %lx\n", dnDevInst, debugstr_guid(InterfaceClassGuid),
04707           pszReference, pszDeviceInterface, pulLength, ulFlags);
04708 
04709     return CM_Register_Device_Interface_ExA(dnDevInst, InterfaceClassGuid,
04710                                             pszReference, pszDeviceInterface,
04711                                             pulLength, ulFlags, NULL);
04712 }
04713 
04714 
04715 /***********************************************************************
04716  * CM_Register_Device_InterfaceW [SETUPAPI.@]
04717  */
04718 CONFIGRET WINAPI CM_Register_Device_InterfaceW(
04719     DEVINST dnDevInst, LPGUID InterfaceClassGuid, LPCWSTR pszReference,
04720     LPWSTR pszDeviceInterface, PULONG pulLength, ULONG ulFlags)
04721 {
04722     TRACE("%lx %s %s %p %p %lx\n", dnDevInst, debugstr_guid(InterfaceClassGuid),
04723           debugstr_w(pszReference), pszDeviceInterface, pulLength, ulFlags);
04724 
04725     return CM_Register_Device_Interface_ExW(dnDevInst, InterfaceClassGuid,
04726                                             pszReference, pszDeviceInterface,
04727                                             pulLength, ulFlags, NULL);
04728 }
04729 
04730 
04731 /***********************************************************************
04732  * CM_Register_Device_Interface_ExA [SETUPAPI.@]
04733  */
04734 CONFIGRET WINAPI CM_Register_Device_Interface_ExA(
04735     DEVINST dnDevInst, LPGUID InterfaceClassGuid, LPCSTR pszReference,
04736     LPSTR pszDeviceInterface, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
04737 {
04738     LPWSTR pszReferenceW = NULL;
04739     LPWSTR pszDeviceInterfaceW = NULL;
04740     ULONG ulLength;
04741     CONFIGRET ret;
04742 
04743     TRACE("%lx %s %s %p %p %lx %lx\n", dnDevInst, debugstr_guid(InterfaceClassGuid),
04744           pszReference, pszDeviceInterface, pulLength, ulFlags, hMachine);
04745 
04746     if (pulLength == NULL || pszDeviceInterface == NULL)
04747         return CR_INVALID_POINTER;
04748 
04749     if (pszReference != NULL)
04750     {
04751         if (pSetupCaptureAndConvertAnsiArg(pszReference, &pszReferenceW))
04752             return CR_INVALID_DATA;
04753     }
04754 
04755     ulLength = *pulLength;
04756 
04757     pszDeviceInterfaceW = HeapAlloc(GetProcessHeap(), 0, ulLength * sizeof(WCHAR));
04758     if (pszDeviceInterfaceW == NULL)
04759     {
04760         ret = CR_OUT_OF_MEMORY;
04761         goto Done;
04762     }
04763 
04764     ret = CM_Register_Device_Interface_ExW(dnDevInst,
04765                                            InterfaceClassGuid,
04766                                            pszReferenceW,
04767                                            pszDeviceInterfaceW,
04768                                            &ulLength,
04769                                            ulFlags,
04770                                            hMachine);
04771     if (ret == CR_SUCCESS)
04772     {
04773         if (WideCharToMultiByte(CP_ACP,
04774                                 0,
04775                                 pszDeviceInterfaceW,
04776                                 ulLength,
04777                                 pszDeviceInterface,
04778                                 *pulLength,
04779                                 NULL,
04780                                 NULL) == 0)
04781             ret = CR_FAILURE;
04782     }
04783 
04784     *pulLength = ulLength;
04785 
04786 Done:
04787     if (pszDeviceInterfaceW != NULL)
04788         HeapFree(GetProcessHeap(), 0, pszDeviceInterfaceW);
04789 
04790     if (pszReferenceW != NULL)
04791         MyFree(pszReferenceW);
04792 
04793     return ret;
04794 }
04795 
04796 
04797 /***********************************************************************
04798  * CM_Register_Device_Interface_ExW [SETUPAPI.@]
04799  */
04800 CONFIGRET WINAPI CM_Register_Device_Interface_ExW(
04801     DEVINST dnDevInst, LPGUID InterfaceClassGuid, LPCWSTR pszReference,
04802     LPWSTR pszDeviceInterface, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
04803 {
04804     RPC_BINDING_HANDLE BindingHandle = NULL;
04805     HSTRING_TABLE StringTable = NULL;
04806     LPWSTR lpDevInst;
04807     ULONG ulTransferLength;
04808     CONFIGRET ret;
04809 
04810     TRACE("%lx %s %s %p %p %lx %lx\n", dnDevInst, debugstr_guid(InterfaceClassGuid),
04811           debugstr_w(pszReference), pszDeviceInterface, pulLength, ulFlags, hMachine);
04812 
04813     if (dnDevInst == 0)
04814         return CR_INVALID_DEVNODE;
04815 
04816     if (InterfaceClassGuid == NULL ||
04817         pszDeviceInterface == NULL ||
04818         pulLength == NULL)
04819         return CR_INVALID_POINTER;
04820 
04821     if (ulFlags != 0)
04822         return CR_INVALID_FLAG;
04823 
04824     if (hMachine != NULL)
04825     {
04826         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
04827         if (BindingHandle == NULL)
04828             return CR_FAILURE;
04829 
04830         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
04831         if (StringTable == 0)
04832             return CR_FAILURE;
04833     }
04834     else
04835     {
04836         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
04837             return CR_FAILURE;
04838     }
04839 
04840     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
04841     if (lpDevInst == NULL)
04842         return CR_INVALID_DEVNODE;
04843 
04844     ulTransferLength = *pulLength;
04845 
04846     RpcTryExcept
04847     {
04848         ret = PNP_RegisterDeviceClassAssociation(BindingHandle,
04849                                                  lpDevInst,
04850                                                  InterfaceClassGuid,
04851                                                  (LPWSTR)pszReference,
04852                                                  pszDeviceInterface,
04853                                                  pulLength,
04854                                                  &ulTransferLength,
04855                                                  0);
04856     }
04857     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
04858     {
04859         ret = RpcStatusToCmStatus(RpcExceptionCode());
04860     }
04861     RpcEndExcept;
04862 
04863     return ret;
04864 }
04865 
04866 
04867 /***********************************************************************
04868  * CM_Register_Device_Driver [SETUPAPI.@]
04869  */
04870 CONFIGRET WINAPI CM_Register_Device_Driver(
04871     DEVINST dnDevInst, ULONG ulFlags)
04872 {
04873     TRACE("%lx 0x%08lx\n", dnDevInst, ulFlags);
04874     return CM_Register_Device_Driver_Ex(dnDevInst, ulFlags, NULL);
04875 }
04876 
04877 
04878 /***********************************************************************
04879  * CM_Register_Device_Driver [SETUPAPI.@]
04880  */
04881 CONFIGRET WINAPI CM_Register_Device_Driver_Ex(
04882     DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
04883 {
04884     RPC_BINDING_HANDLE BindingHandle = NULL;
04885     HSTRING_TABLE StringTable = NULL;
04886     LPWSTR lpDevInst;
04887     CONFIGRET ret;
04888 
04889     TRACE("%lx 0x%08lx %p\n", dnDevInst, ulFlags, hMachine);
04890 
04891     if (dnDevInst == 0)
04892         return CR_INVALID_DEVNODE;
04893 
04894     if (ulFlags & ~CM_REGISTER_DEVICE_DRIVER_BITS)
04895         return CR_INVALID_FLAG;
04896 
04897     if (hMachine != NULL)
04898     {
04899         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
04900         if (BindingHandle == NULL)
04901             return CR_FAILURE;
04902 
04903         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
04904         if (StringTable == 0)
04905             return CR_FAILURE;
04906     }
04907     else
04908     {
04909         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
04910             return CR_FAILURE;
04911     }
04912 
04913     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
04914     if (lpDevInst == NULL)
04915         return CR_INVALID_DEVNODE;
04916 
04917     RpcTryExcept
04918     {
04919         ret = PNP_RegisterDriver(BindingHandle,
04920                                  lpDevInst,
04921                                  ulFlags);
04922     }
04923     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
04924     {
04925         ret = RpcStatusToCmStatus(RpcExceptionCode());
04926     }
04927     RpcEndExcept;
04928 
04929     return ret;
04930 }
04931 
04932 
04933 /***********************************************************************
04934  * CM_Remove_SubTree [SETUPAPI.@]
04935  *
04936  * This function is obsolete in Windows XP and above.
04937  */
04938 CONFIGRET WINAPI CM_Remove_SubTree(
04939     DEVINST dnAncestor, ULONG ulFlags)
04940 {
04941     TRACE("%lx %lx\n", dnAncestor, ulFlags);
04942     return CR_CALL_NOT_IMPLEMENTED;
04943 }
04944 
04945 
04946 /***********************************************************************
04947  * CM_Remove_SubTree_Ex [SETUPAPI.@]
04948  *
04949  * This function is obsolete in Windows XP and above.
04950  */
04951 CONFIGRET WINAPI CM_Remove_SubTree_Ex(
04952     DEVINST dnAncestor, ULONG ulFlags, HMACHINE hMachine)
04953 {
04954     TRACE("%lx %lx %lx\n", dnAncestor, ulFlags, hMachine);
04955     return CR_CALL_NOT_IMPLEMENTED;
04956 }
04957 
04958 
04959 /***********************************************************************
04960  * CM_Request_Device_EjectA [SETUPAPI.@]
04961  */
04962 CONFIGRET WINAPI CM_Request_Device_EjectA(
04963     DEVINST dnDevInst, PPNP_VETO_TYPE pVetoType, LPSTR pszVetoName,
04964     ULONG ulNameLength, ULONG ulFlags)
04965 {
04966     TRACE("%lx %p %s %lu %lx\n", dnDevInst, pVetoType, pszVetoName,
04967           ulNameLength, ulFlags);
04968     return CM_Request_Device_Eject_ExA(dnDevInst, pVetoType, pszVetoName,
04969                                        ulNameLength, ulFlags, NULL);
04970 }
04971 
04972 
04973 /***********************************************************************
04974  * CM_Request_Device_EjectW [SETUPAPI.@]
04975  */
04976 CONFIGRET WINAPI CM_Request_Device_EjectW(
04977     DEVINST dnDevInst, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName,
04978     ULONG ulNameLength, ULONG ulFlags)
04979 {
04980     TRACE("%lx %p %s %lu %lx\n", dnDevInst, pVetoType, debugstr_w(pszVetoName),
04981           ulNameLength, ulFlags);
04982     return CM_Request_Device_Eject_ExW(dnDevInst, pVetoType, pszVetoName,
04983                                        ulNameLength, ulFlags, NULL);
04984 }
04985 
04986 
04987 /***********************************************************************
04988  * CM_Request_Device_Eject_ExA [SETUPAPI.@]
04989  */
04990 CONFIGRET WINAPI CM_Request_Device_Eject_ExA(
04991     DEVINST dnDevInst, PPNP_VETO_TYPE pVetoType, LPSTR pszVetoName,
04992     ULONG ulNameLength, ULONG ulFlags, HMACHINE hMachine)
04993 {
04994     LPWSTR lpLocalVetoName;
04995     CONFIGRET ret;
04996 
04997     TRACE("%lx %p %s %lu %lx %lx\n", dnDevInst, pVetoType, pszVetoName,
04998           ulNameLength, ulFlags, hMachine);
04999 
05000     if (pszVetoName == NULL && ulNameLength == 0)
05001         return CR_INVALID_POINTER;
05002 
05003     lpLocalVetoName = HeapAlloc(GetProcessHeap(), 0, ulNameLength * sizeof(WCHAR));
05004     if (lpLocalVetoName == NULL)
05005         return CR_OUT_OF_MEMORY;
05006 
05007     ret = CM_Request_Device_Eject_ExW(dnDevInst, pVetoType, lpLocalVetoName,
05008                                       ulNameLength, ulFlags, hMachine);
05009     if (ret == CR_REMOVE_VETOED)
05010     {
05011         if (WideCharToMultiByte(CP_ACP,
05012                                 0,
05013                                 lpLocalVetoName,
05014                                 ulNameLength,
05015                                 pszVetoName,
05016                                 ulNameLength,
05017                                 NULL,
05018                                 NULL) == 0)
05019             ret = CR_FAILURE;
05020     }
05021 
05022     HeapFree(GetProcessHeap(), 0, lpLocalVetoName);
05023 
05024     return ret;
05025 }
05026 
05027 
05028 /***********************************************************************
05029  * CM_Request_Device_Eject_ExW [SETUPAPI.@]
05030  */
05031 CONFIGRET WINAPI CM_Request_Device_Eject_ExW(
05032     DEVINST dnDevInst, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName,
05033     ULONG ulNameLength, ULONG ulFlags, HMACHINE hMachine)
05034 {
05035     RPC_BINDING_HANDLE BindingHandle = NULL;
05036     HSTRING_TABLE StringTable = NULL;
05037     LPWSTR lpDevInst;
05038     CONFIGRET ret;
05039 
05040     TRACE("%lx %p %s %lu %lx %lx\n", dnDevInst, pVetoType,
05041           debugstr_w(pszVetoName), ulNameLength, ulFlags, hMachine);
05042 
05043     if (dnDevInst == 0)
05044         return CR_INVALID_DEVNODE;
05045 
05046     if (ulFlags != 0)
05047         return CR_INVALID_FLAG;
05048 
05049     if (pszVetoName == NULL && ulNameLength == 0)
05050         return CR_INVALID_POINTER;
05051 
05052     if (hMachine != NULL)
05053     {
05054         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
05055         if (BindingHandle == NULL)
05056             return CR_FAILURE;
05057 
05058         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
05059         if (StringTable == 0)
05060             return CR_FAILURE;
05061     }
05062     else
05063     {
05064         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
05065             return CR_FAILURE;
05066     }
05067 
05068     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
05069     if (lpDevInst == NULL)
05070         return CR_INVALID_DEVNODE;
05071 
05072     RpcTryExcept
05073     {
05074         ret = PNP_RequestDeviceEject(BindingHandle,
05075                                      lpDevInst,
05076                                      pVetoType,
05077                                      pszVetoName,
05078                                      ulNameLength,
05079                                      ulFlags);
05080     }
05081     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
05082     {
05083         ret = RpcStatusToCmStatus(RpcExceptionCode());
05084     }
05085     RpcEndExcept;
05086 
05087     return ret;
05088 }
05089 
05090 
05091 /***********************************************************************
05092  * CM_Request_Eject_PC [SETUPAPI.@]
05093  */
05094 CONFIGRET WINAPI CM_Request_Eject_PC(VOID)
05095 {
05096     TRACE("\n");
05097     return CM_Request_Eject_PC_Ex(NULL);
05098 }
05099 
05100 
05101 /***********************************************************************
05102  * CM_Request_Eject_PC_Ex [SETUPAPI.@]
05103  */
05104 CONFIGRET WINAPI CM_Request_Eject_PC_Ex(
05105     HMACHINE hMachine)
05106 {
05107     RPC_BINDING_HANDLE BindingHandle = NULL;
05108     CONFIGRET ret;
05109 
05110     TRACE("%lx\n", hMachine);
05111 
05112     if (hMachine != NULL)
05113     {
05114         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
05115         if (BindingHandle == NULL)
05116             return CR_FAILURE;
05117     }
05118     else
05119     {
05120         if (!PnpGetLocalHandles(&BindingHandle, NULL))
05121             return CR_FAILURE;
05122     }
05123 
05124     RpcTryExcept
05125     {
05126         ret = PNP_RequestEjectPC(BindingHandle);
05127     }
05128     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
05129     {
05130         ret = RpcStatusToCmStatus(RpcExceptionCode());
05131     }
05132     RpcEndExcept;
05133 
05134     return ret;
05135 }
05136 
05137 
05138 /***********************************************************************
05139  * CM_Run_Detection [SETUPAPI.@]
05140  */
05141 CONFIGRET WINAPI CM_Run_Detection(
05142     ULONG ulFlags)
05143 {
05144     TRACE("%lx\n", ulFlags);
05145     return CM_Run_Detection_Ex(ulFlags, NULL);
05146 }
05147 
05148 
05149 /***********************************************************************
05150  * CM_Run_Detection_Ex [SETUPAPI.@]
05151  */
05152 CONFIGRET WINAPI CM_Run_Detection_Ex(
05153     ULONG ulFlags, HMACHINE hMachine)
05154 {
05155     RPC_BINDING_HANDLE BindingHandle = NULL;
05156     CONFIGRET ret;
05157 
05158     TRACE("%lx %lx\n", ulFlags, hMachine);
05159 
05160     if (!pSetupIsUserAdmin())
05161         return CR_ACCESS_DENIED;
05162 
05163     if (ulFlags & ~CM_DETECT_BITS)
05164         return CR_INVALID_FLAG;
05165 
05166     if (hMachine != NULL)
05167     {
05168         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
05169         if (BindingHandle == NULL)
05170             return CR_FAILURE;
05171     }
05172     else
05173     {
05174         if (!PnpGetLocalHandles(&BindingHandle, NULL))
05175             return CR_FAILURE;
05176     }
05177 
05178     RpcTryExcept
05179     {
05180         ret = PNP_RunDetection(BindingHandle,
05181                                ulFlags);
05182     }
05183     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
05184     {
05185         ret = RpcStatusToCmStatus(RpcExceptionCode());
05186     }
05187     RpcEndExcept;
05188 
05189     return ret;
05190 }
05191 
05192 
05193 /***********************************************************************
05194  * CM_Set_Class_Registry_PropertyA [SETUPAPI.@]
05195  */
05196 CONFIGRET WINAPI CM_Set_Class_Registry_PropertyA(
05197     LPGUID ClassGuid, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
05198     ULONG ulFlags, HMACHINE hMachine)
05199 {
05200     FIXME("%p %lx %p %lu %lx %p\n",
05201           ClassGuid, ulProperty, Buffer, ulLength, ulFlags, hMachine);
05202     return CR_CALL_NOT_IMPLEMENTED;
05203 }
05204 
05205 
05206 /***********************************************************************
05207  * CM_Set_Class_Registry_PropertyW [SETUPAPI.@]
05208  */
05209 CONFIGRET WINAPI CM_Set_Class_Registry_PropertyW(
05210     LPGUID ClassGuid, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
05211     ULONG ulFlags, HMACHINE hMachine)
05212 {
05213     FIXME("%p %lx %p %lu %lx %p\n",
05214           ClassGuid, ulProperty, Buffer, ulLength, ulFlags, hMachine);
05215     return CR_CALL_NOT_IMPLEMENTED;
05216 }
05217 
05218 
05219 /***********************************************************************
05220  * CM_Set_DevNode_Problem [SETUPAPI.@]
05221  */
05222 CONFIGRET WINAPI CM_Set_DevNode_Problem(
05223     DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags)
05224 {
05225     TRACE("%lx %lx %lx\n", dnDevInst, ulProblem, ulFlags);
05226     return CM_Set_DevNode_Problem_Ex(dnDevInst, ulProblem, ulFlags, NULL);
05227 }
05228 
05229 
05230 /***********************************************************************
05231  * CM_Set_DevNode_Problem_Ex [SETUPAPI.@]
05232  */
05233 CONFIGRET WINAPI CM_Set_DevNode_Problem_Ex(
05234     DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags, HMACHINE hMachine)
05235 {
05236     RPC_BINDING_HANDLE BindingHandle = NULL;
05237     HSTRING_TABLE StringTable = NULL;
05238     LPWSTR lpDevInst;
05239     CONFIGRET ret;
05240 
05241     TRACE("%lx %lx %lx %lx\n", dnDevInst, ulProblem, ulFlags, hMachine);
05242 
05243     if (dnDevInst == 0)
05244         return CR_INVALID_DEVNODE;
05245 
05246     if (ulFlags & ~CM_SET_DEVNODE_PROBLEM_BITS)
05247         return CR_INVALID_FLAG;
05248 
05249     if (hMachine != NULL)
05250     {
05251         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
05252         if (BindingHandle == NULL)
05253             return CR_FAILURE;
05254 
05255         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
05256         if (StringTable == 0)
05257             return CR_FAILURE;
05258     }
05259     else
05260     {
05261         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
05262             return CR_FAILURE;
05263     }
05264 
05265     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
05266     if (lpDevInst == NULL)
05267         return CR_INVALID_DEVNODE;
05268 
05269     RpcTryExcept
05270     {
05271         ret = PNP_SetDeviceProblem(BindingHandle,
05272                                    lpDevInst,
05273                                    ulProblem,
05274                                    ulFlags);
05275     }
05276     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
05277     {
05278         ret = RpcStatusToCmStatus(RpcExceptionCode());
05279     }
05280     RpcEndExcept;
05281 
05282     return ret;
05283 }
05284 
05285 
05286 /***********************************************************************
05287  * CM_Set_DevNode_Registry_PropertyA [SETUPAPI.@]
05288  */
05289 CONFIGRET WINAPI CM_Set_DevNode_Registry_PropertyA(
05290     DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
05291     ULONG ulFlags)
05292 {
05293     TRACE("%lx %lu %p %lx %lx\n",
05294           dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
05295     return CM_Set_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
05296                                                 Buffer, ulLength,
05297                                                 ulFlags, NULL);
05298 }
05299 
05300 
05301 /***********************************************************************
05302  * CM_Set_DevNode_Registry_PropertyW [SETUPAPI.@]
05303  */
05304 CONFIGRET WINAPI CM_Set_DevNode_Registry_PropertyW(
05305     DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
05306     ULONG ulFlags)
05307 {
05308     TRACE("%lx %lu %p %lx %lx\n",
05309           dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
05310     return CM_Set_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
05311                                                 Buffer, ulLength,
05312                                                 ulFlags, NULL);
05313 }
05314 
05315 
05316 /***********************************************************************
05317  * CM_Set_DevNode_Registry_Property_ExA [SETUPAPI.@]
05318  */
05319 CONFIGRET WINAPI CM_Set_DevNode_Registry_Property_ExA(
05320     DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
05321     ULONG ulFlags, HMACHINE hMachine)
05322 {
05323     CONFIGRET ret = CR_SUCCESS;
05324     LPWSTR lpBuffer;
05325     ULONG ulType;
05326 
05327     FIXME("%lx %lu %p %lx %lx %lx\n",
05328           dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
05329 
05330     if (Buffer == NULL && ulLength != 0)
05331         return CR_INVALID_POINTER;
05332 
05333     if (Buffer == NULL)
05334     {
05335         ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
05336                                                    ulProperty,
05337                                                    NULL,
05338                                                    0,
05339                                                    ulFlags,
05340                                                    hMachine);
05341     }
05342     else
05343     {
05344         /* Get property type */
05345         switch (ulProperty)
05346         {
05347             case CM_DRP_DEVICEDESC:
05348                 ulType = REG_SZ;
05349                 break;
05350 
05351             case CM_DRP_HARDWAREID:
05352                 ulType = REG_MULTI_SZ;
05353                 break;
05354 
05355             case CM_DRP_COMPATIBLEIDS:
05356                 ulType = REG_MULTI_SZ;
05357                 break;
05358 
05359             case CM_DRP_SERVICE:
05360                 ulType = REG_SZ;
05361                 break;
05362 
05363             case CM_DRP_CLASS:
05364                 ulType = REG_SZ;
05365                 break;
05366 
05367             case CM_DRP_CLASSGUID:
05368                 ulType = REG_SZ;
05369                 break;
05370 
05371             case CM_DRP_DRIVER:
05372                 ulType = REG_SZ;
05373                 break;
05374 
05375             case CM_DRP_CONFIGFLAGS:
05376                 ulType = REG_DWORD;
05377                 break;
05378 
05379             case CM_DRP_MFG:
05380                 ulType = REG_SZ;
05381                 break;
05382 
05383             case CM_DRP_FRIENDLYNAME:
05384                 ulType = REG_SZ;
05385                 break;
05386 
05387             case CM_DRP_LOCATION_INFORMATION:
05388                 ulType = REG_SZ;
05389                 break;
05390 
05391             case CM_DRP_UPPERFILTERS:
05392                 ulType = REG_MULTI_SZ;
05393                 break;
05394 
05395             case CM_DRP_LOWERFILTERS:
05396                 ulType = REG_MULTI_SZ;
05397                 break;
05398 
05399             case CM_DRP_SECURITY:
05400                 ulType = REG_BINARY;
05401                 break;
05402 
05403             case CM_DRP_DEVTYPE:
05404                 ulType = REG_DWORD;
05405                 break;
05406 
05407             case CM_DRP_EXCLUSIVE:
05408                 ulType = REG_DWORD;
05409                 break;
05410 
05411             case CM_DRP_CHARACTERISTICS:
05412                 ulType = REG_DWORD;
05413                 break;
05414 
05415             case CM_DRP_UI_NUMBER_DESC_FORMAT:
05416                 ulType = REG_SZ;
05417                 break;
05418 
05419             case CM_DRP_REMOVAL_POLICY_OVERRIDE:
05420                 ulType = REG_DWORD;
05421                 break;
05422 
05423             default:
05424                 return CR_INVALID_PROPERTY;
05425         }
05426 
05427         /* Allocate buffer if needed */
05428         if (ulType == REG_SZ ||
05429             ulType == REG_MULTI_SZ)
05430         {
05431             lpBuffer = MyMalloc(ulLength * sizeof(WCHAR));
05432             if (lpBuffer == NULL)
05433             {
05434                 ret = CR_OUT_OF_MEMORY;
05435             }
05436             else
05437             {
05438                 if (!MultiByteToWideChar(CP_ACP, 0, Buffer,
05439                                          ulLength, lpBuffer, ulLength))
05440                 {
05441                     MyFree(lpBuffer);
05442                     ret = CR_FAILURE;
05443                 }
05444                 else
05445                 {
05446                     ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
05447                                                                ulProperty,
05448                                                                lpBuffer,
05449                                                                ulLength * sizeof(WCHAR),
05450                                                                ulFlags,
05451                                                                hMachine);
05452                     MyFree(lpBuffer);
05453                 }
05454             }
05455         }
05456         else
05457         {
05458             ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
05459                                                        ulProperty,
05460                                                        Buffer,
05461                                                        ulLength,
05462                                                        ulFlags,
05463                                                        hMachine);
05464         }
05465 
05466         ret = CR_CALL_NOT_IMPLEMENTED;
05467     }
05468 
05469     return ret;
05470 }
05471 
05472 
05473 /***********************************************************************
05474  * CM_Set_DevNode_Registry_Property_ExW [SETUPAPI.@]
05475  */
05476 CONFIGRET WINAPI CM_Set_DevNode_Registry_Property_ExW(
05477     DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
05478     ULONG ulFlags, HMACHINE hMachine)
05479 {
05480     RPC_BINDING_HANDLE BindingHandle = NULL;
05481     HSTRING_TABLE StringTable = NULL;
05482     LPWSTR lpDevInst;
05483     ULONG ulType;
05484     CONFIGRET ret;
05485 
05486     TRACE("%lx %lu %p %lx %lx %lx\n",
05487           dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
05488 
05489     if (dnDevInst == 0)
05490         return CR_INVALID_DEVNODE;
05491 
05492     if (ulProperty <  CM_DRP_MIN || ulProperty > CM_DRP_MAX)
05493         return CR_INVALID_PROPERTY;
05494 
05495     if (Buffer != NULL && ulLength == 0)
05496         return CR_INVALID_POINTER;
05497 
05498     if (ulFlags != 0)
05499         return CR_INVALID_FLAG;
05500 
05501     if (hMachine != NULL)
05502     {
05503         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
05504         if (BindingHandle == NULL)
05505             return CR_FAILURE;
05506 
05507         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
05508         if (StringTable == 0)
05509             return CR_FAILURE;
05510     }
05511     else
05512     {
05513         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
05514             return CR_FAILURE;
05515     }
05516 
05517     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
05518     if (lpDevInst == NULL)
05519         return CR_INVALID_DEVNODE;
05520 
05521     switch (ulProperty)
05522     {
05523         case CM_DRP_DEVICEDESC:
05524             ulType = REG_SZ;
05525             break;
05526 
05527         case CM_DRP_HARDWAREID:
05528             ulType = REG_MULTI_SZ;
05529             break;
05530 
05531         case CM_DRP_COMPATIBLEIDS:
05532             ulType = REG_MULTI_SZ;
05533             break;
05534 
05535         case CM_DRP_SERVICE:
05536             ulType = REG_SZ;
05537             break;
05538 
05539         case CM_DRP_CLASS:
05540             ulType = REG_SZ;
05541             break;
05542 
05543         case CM_DRP_CLASSGUID:
05544             ulType = REG_SZ;
05545             break;
05546 
05547         case CM_DRP_DRIVER:
05548             ulType = REG_SZ;
05549             break;
05550 
05551         case CM_DRP_CONFIGFLAGS:
05552             ulType = REG_DWORD;
05553             break;
05554 
05555         case CM_DRP_MFG:
05556             ulType = REG_SZ;
05557             break;
05558 
05559         case CM_DRP_FRIENDLYNAME:
05560             ulType = REG_SZ;
05561             break;
05562 
05563         case CM_DRP_LOCATION_INFORMATION:
05564             ulType = REG_SZ;
05565             break;
05566 
05567         case CM_DRP_UPPERFILTERS:
05568             ulType = REG_MULTI_SZ;
05569             break;
05570 
05571         case CM_DRP_LOWERFILTERS:
05572             ulType = REG_MULTI_SZ;
05573             break;
05574 
05575         case CM_DRP_SECURITY:
05576             ulType = REG_BINARY;
05577             break;
05578 
05579         case CM_DRP_DEVTYPE:
05580             ulType = REG_DWORD;
05581             break;
05582 
05583         case CM_DRP_EXCLUSIVE:
05584             ulType = REG_DWORD;
05585             break;
05586 
05587         case CM_DRP_CHARACTERISTICS:
05588             ulType = REG_DWORD;
05589             break;
05590 
05591         case CM_DRP_UI_NUMBER_DESC_FORMAT:
05592             ulType = REG_SZ;
05593             break;
05594 
05595         case CM_DRP_REMOVAL_POLICY_OVERRIDE:
05596             ulType = REG_DWORD;
05597             break;
05598 
05599         default:
05600             return CR_INVALID_PROPERTY;
05601     }
05602 
05603     RpcTryExcept
05604     {
05605         ret = PNP_SetDeviceRegProp(BindingHandle,
05606                                    lpDevInst,
05607                                    ulProperty,
05608                                    ulType,
05609                                    (BYTE *)Buffer,
05610                                    ulLength,
05611                                    ulFlags);
05612     }
05613     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
05614     {
05615         ret = RpcStatusToCmStatus(RpcExceptionCode());
05616     }
05617     RpcEndExcept;
05618 
05619     return ret;
05620 }
05621 
05622 
05623 /***********************************************************************
05624  * CM_Set_HW_Prof [SETUPAPI.@]
05625  */
05626 CONFIGRET WINAPI CM_Set_HW_Prof(
05627     ULONG ulHardwareProfile, ULONG ulFlags)
05628 {
05629     TRACE("%lu %lu\n", ulHardwareProfile, ulFlags);
05630     return CM_Set_HW_Prof_Ex(ulHardwareProfile, ulFlags, NULL);
05631 }
05632 
05633 
05634 /***********************************************************************
05635  * CM_Set_HW_Prof_Ex [SETUPAPI.@]
05636  */
05637 CONFIGRET WINAPI CM_Set_HW_Prof_Ex(
05638     ULONG ulHardwareProfile, ULONG ulFlags, HMACHINE hMachine)
05639 {
05640     RPC_BINDING_HANDLE BindingHandle = NULL;
05641     CONFIGRET ret;
05642 
05643     TRACE("%lu %lu %lx\n", ulHardwareProfile, ulFlags, hMachine);
05644 
05645     if (!pSetupIsUserAdmin())
05646         return CR_ACCESS_DENIED;
05647 
05648     if (ulFlags != 0)
05649         return CR_INVALID_FLAG;
05650 
05651     if (hMachine != NULL)
05652     {
05653         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
05654         if (BindingHandle == NULL)
05655             return CR_FAILURE;
05656     }
05657     else
05658     {
05659         if (!PnpGetLocalHandles(&BindingHandle, NULL))
05660             return CR_FAILURE;
05661     }
05662 
05663     RpcTryExcept
05664     {
05665         ret = PNP_SetHwProf(BindingHandle, ulHardwareProfile, ulFlags);
05666     }
05667     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
05668     {
05669         ret = RpcStatusToCmStatus(RpcExceptionCode());
05670     }
05671     RpcEndExcept;
05672 
05673     return ret;
05674 }
05675 
05676 
05677 /***********************************************************************
05678  * CM_Set_HW_Prof_FlagsA [SETUPAPI.@]
05679  */
05680 CONFIGRET WINAPI CM_Set_HW_Prof_FlagsA(
05681     DEVINSTID_A szDevInstName, ULONG ulConfig, ULONG ulValue,
05682     ULONG ulFlags)
05683 {
05684     TRACE("%s %lu %lu %lx\n", szDevInstName,
05685           ulConfig, ulValue, ulFlags);
05686     return CM_Set_HW_Prof_Flags_ExA(szDevInstName, ulConfig, ulValue,
05687                                     ulFlags, NULL);
05688 }
05689 
05690 
05691 /***********************************************************************
05692  * CM_Set_HW_Prof_FlagsW [SETUPAPI.@]
05693  */
05694 CONFIGRET WINAPI CM_Set_HW_Prof_FlagsW(
05695     DEVINSTID_W szDevInstName, ULONG ulConfig, ULONG ulValue,
05696     ULONG ulFlags)
05697 {
05698     TRACE("%s %lu %lu %lx\n", debugstr_w(szDevInstName),
05699           ulConfig, ulValue, ulFlags);
05700     return CM_Set_HW_Prof_Flags_ExW(szDevInstName, ulConfig, ulValue,
05701                                     ulFlags, NULL);
05702 }
05703 
05704 
05705 /***********************************************************************
05706  * CM_Set_HW_Prof_Flags_ExA [SETUPAPI.@]
05707  */
05708 CONFIGRET WINAPI CM_Set_HW_Prof_Flags_ExA(
05709     DEVINSTID_A szDevInstName, ULONG ulConfig, ULONG ulValue,
05710     ULONG ulFlags, HMACHINE hMachine)
05711 {
05712     DEVINSTID_W pszDevIdW = NULL;
05713     CONFIGRET ret = CR_SUCCESS;
05714 
05715     TRACE("%s %lu %lu %lx %lx\n", szDevInstName,
05716           ulConfig, ulValue, ulFlags, hMachine);
05717 
05718     if (szDevInstName != NULL)
05719     {
05720        if (pSetupCaptureAndConvertAnsiArg(szDevInstName, &pszDevIdW))
05721          return CR_INVALID_DEVICE_ID;
05722     }
05723 
05724     ret = CM_Set_HW_Prof_Flags_ExW(pszDevIdW, ulConfig, ulValue,
05725                                    ulFlags, hMachine);
05726 
05727     if (pszDevIdW != NULL)
05728         MyFree(pszDevIdW);
05729 
05730     return ret;
05731 }
05732 
05733 
05734 /***********************************************************************
05735  * CM_Set_HW_Prof_Flags_ExW [SETUPAPI.@]
05736  */
05737 CONFIGRET WINAPI CM_Set_HW_Prof_Flags_ExW(
05738     DEVINSTID_W szDevInstName, ULONG ulConfig, ULONG ulValue,
05739     ULONG ulFlags, HMACHINE hMachine)
05740 {
05741     RPC_BINDING_HANDLE BindingHandle = NULL;
05742     CONFIGRET ret;
05743 
05744     FIXME("%s %lu %lu %lx %lx\n", debugstr_w(szDevInstName),
05745           ulConfig, ulValue, ulFlags, hMachine);
05746 
05747     if (szDevInstName == NULL)
05748         return CR_INVALID_POINTER;
05749 
05750     if (ulFlags & ~ CM_SET_HW_PROF_FLAGS_BITS)
05751         return CR_INVALID_FLAG;
05752 
05753     /* FIXME: Check whether szDevInstName is valid */
05754 
05755     if (hMachine != NULL)
05756     {
05757         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
05758         if (BindingHandle == NULL)
05759             return CR_FAILURE;
05760     }
05761     else
05762     {
05763         if (!PnpGetLocalHandles(&BindingHandle, NULL))
05764             return CR_FAILURE;
05765     }
05766 
05767     RpcTryExcept
05768     {
05769         ret = PNP_HwProfFlags(BindingHandle, PNP_SET_HWPROFFLAGS, szDevInstName,
05770                               ulConfig, &ulValue, NULL, NULL, 0, 0);
05771     }
05772     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
05773     {
05774         ret = RpcStatusToCmStatus(RpcExceptionCode());
05775     }
05776     RpcEndExcept;
05777 
05778     return ret;
05779 }
05780 
05781 
05782 /***********************************************************************
05783  * CM_Setup_DevNode [SETUPAPI.@]
05784  */
05785 CONFIGRET WINAPI CM_Setup_DevNode(
05786     DEVINST dnDevInst, ULONG ulFlags)
05787 {
05788     TRACE("%lx %lx\n", dnDevInst, ulFlags);
05789     return CM_Setup_DevNode_Ex(dnDevInst, ulFlags, NULL);
05790 }
05791 
05792 
05793 /***********************************************************************
05794  * CM_Setup_DevNode_Ex [SETUPAPI.@]
05795  */
05796 CONFIGRET WINAPI CM_Setup_DevNode_Ex(
05797     DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
05798 {
05799     RPC_BINDING_HANDLE BindingHandle = NULL;
05800     HSTRING_TABLE StringTable = NULL;
05801     LPWSTR lpDevInst;
05802     CONFIGRET ret;
05803 
05804     FIXME("%lx %lx %lx\n", dnDevInst, ulFlags, hMachine);
05805 
05806     if (!pSetupIsUserAdmin())
05807         return CR_ACCESS_DENIED;
05808 
05809     if (dnDevInst == 0)
05810         return CR_INVALID_DEVNODE;
05811 
05812     if (ulFlags & ~CM_SETUP_BITS)
05813         return CR_INVALID_FLAG;
05814 
05815     if (hMachine != NULL)
05816     {
05817         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
05818         if (BindingHandle == NULL)
05819             return CR_FAILURE;
05820 
05821         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
05822         if (StringTable == 0)
05823             return CR_FAILURE;
05824     }
05825     else
05826     {
05827         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
05828             return CR_FAILURE;
05829     }
05830 
05831     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
05832     if (lpDevInst == NULL)
05833         return CR_INVALID_DEVNODE;
05834 
05835     RpcTryExcept
05836     {
05837         ret = PNP_DeviceInstanceAction(BindingHandle,
05838                                        PNP_DEVINST_SETUP,
05839                                        ulFlags,
05840                                        lpDevInst,
05841                                        NULL);
05842     }
05843     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
05844     {
05845         ret = RpcStatusToCmStatus(RpcExceptionCode());
05846     }
05847     RpcEndExcept;
05848 
05849     return ret;
05850 }
05851 
05852 
05853 /***********************************************************************
05854  * CM_Uninstall_DevNode [SETUPAPI.@]
05855  */
05856 CONFIGRET WINAPI CM_Uninstall_DevNode(
05857     DEVINST dnPhantom, ULONG ulFlags)
05858 {
05859     TRACE("%lx %lx\n", dnPhantom, ulFlags);
05860     return CM_Uninstall_DevNode_Ex(dnPhantom, ulFlags, NULL);
05861 }
05862 
05863 
05864 /***********************************************************************
05865  * CM_Uninstall_DevNode_Ex [SETUPAPI.@]
05866  */
05867 CONFIGRET WINAPI CM_Uninstall_DevNode_Ex(
05868     DEVINST dnPhantom, ULONG ulFlags, HMACHINE hMachine)
05869 {
05870     RPC_BINDING_HANDLE BindingHandle = NULL;
05871     HSTRING_TABLE StringTable = NULL;
05872     LPWSTR lpDevInst;
05873     CONFIGRET ret;
05874 
05875     TRACE("%lx %lx %lx\n", dnPhantom, ulFlags, hMachine);
05876 
05877     if (dnPhantom == 0)
05878         return CR_INVALID_DEVNODE;
05879 
05880     if (ulFlags != 0)
05881         return CR_INVALID_FLAG;
05882 
05883     if (hMachine != NULL)
05884     {
05885         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
05886         if (BindingHandle == NULL)
05887             return CR_FAILURE;
05888 
05889         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
05890         if (StringTable == 0)
05891             return CR_FAILURE;
05892     }
05893     else
05894     {
05895         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
05896             return CR_FAILURE;
05897     }
05898 
05899     lpDevInst = pSetupStringTableStringFromId(StringTable, dnPhantom);
05900     if (lpDevInst == NULL)
05901         return CR_INVALID_DEVNODE;
05902 
05903     RpcTryExcept
05904     {
05905         ret = PNP_UninstallDevInst(BindingHandle,
05906                                    lpDevInst,
05907                                    ulFlags);
05908     }
05909     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
05910     {
05911         ret = RpcStatusToCmStatus(RpcExceptionCode());
05912     }
05913     RpcEndExcept;
05914 
05915     return ret;
05916 }
05917 
05918 
05919 /***********************************************************************
05920  * CM_Unregister_Device_InterfaceA [SETUPAPI.@]
05921  */
05922 CONFIGRET WINAPI CM_Unregister_Device_InterfaceA(
05923     LPCSTR pszDeviceInterface, ULONG ulFlags)
05924 {
05925     TRACE("%s %lx\n", pszDeviceInterface, ulFlags);
05926 
05927     return CM_Unregister_Device_Interface_ExA(pszDeviceInterface,
05928                                               ulFlags, NULL);
05929 }
05930 
05931 
05932 /***********************************************************************
05933  * CM_Unregister_Device_InterfaceW [SETUPAPI.@]
05934  */
05935 CONFIGRET WINAPI CM_Unregister_Device_InterfaceW(
05936     LPCWSTR pszDeviceInterface, ULONG ulFlags)
05937 {
05938     TRACE("%s %lx\n", debugstr_w(pszDeviceInterface), ulFlags);
05939 
05940     return CM_Unregister_Device_Interface_ExW(pszDeviceInterface,
05941                                               ulFlags, NULL);
05942 }
05943 
05944 
05945 /***********************************************************************
05946  * CM_Unregister_Device_Interface_ExA [SETUPAPI.@]
05947  */
05948 CONFIGRET WINAPI CM_Unregister_Device_Interface_ExA(
05949     LPCSTR pszDeviceInterface, ULONG ulFlags, HMACHINE hMachine)
05950 {
05951     LPWSTR pszDeviceInterfaceW = NULL;
05952     CONFIGRET ret;
05953 
05954     TRACE("%s %lx %lx\n", pszDeviceInterface, ulFlags, hMachine);
05955 
05956     if (pszDeviceInterface == NULL)
05957         return CR_INVALID_POINTER;
05958 
05959     if (pSetupCaptureAndConvertAnsiArg(pszDeviceInterface, &pszDeviceInterfaceW))
05960         return CR_INVALID_DATA;
05961 
05962     ret = CM_Unregister_Device_Interface_ExW(pszDeviceInterfaceW,
05963                                              ulFlags, hMachine);
05964 
05965     if (pszDeviceInterfaceW != NULL)
05966         MyFree(pszDeviceInterfaceW);
05967 
05968     return ret;
05969 }
05970 
05971 
05972 /***********************************************************************
05973  * CM_Unregister_Device_Interface_ExW [SETUPAPI.@]
05974  */
05975 CONFIGRET WINAPI CM_Unregister_Device_Interface_ExW(
05976     LPCWSTR pszDeviceInterface, ULONG ulFlags, HMACHINE hMachine)
05977 {
05978     RPC_BINDING_HANDLE BindingHandle = NULL;
05979     CONFIGRET ret;
05980 
05981     TRACE("%s %lx %lx\n", debugstr_w(pszDeviceInterface), ulFlags, hMachine);
05982 
05983     if (pszDeviceInterface == NULL)
05984         return CR_INVALID_POINTER;
05985 
05986     if (ulFlags != 0)
05987         return CR_INVALID_FLAG;
05988 
05989     if (hMachine != NULL)
05990     {
05991         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
05992         if (BindingHandle == NULL)
05993             return CR_FAILURE;
05994     }
05995     else
05996     {
05997         if (!PnpGetLocalHandles(&BindingHandle, NULL))
05998             return CR_FAILURE;
05999     }
06000 
06001     RpcTryExcept
06002     {
06003         ret = PNP_UnregisterDeviceClassAssociation(BindingHandle,
06004                                                    (LPWSTR)pszDeviceInterface,
06005                                                    ulFlags);
06006     }
06007     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
06008     {
06009         ret = RpcStatusToCmStatus(RpcExceptionCode());
06010     }
06011     RpcEndExcept;
06012 
06013     return ret;
06014 }

Generated on Wed May 23 2012 04:23:58 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.