* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* COPYRIGHT: See COPYING in the top level directory
* PURPOSE: User-mode Plug and Play manager
* PROGRAMMER: Eric Kohl
* Hervé Poussineau (hpoussin@reactos.org)
+ * Colin Finck (colin@reactos.org)
*/
/* INCLUDES *****************************************************************/
+//#define HAVE_SLIST_ENTRY_IMPLEMENTED
#define WIN32_NO_STATUS
#include <windows.h>
+#include <stdio.h>
#include <cmtypes.h>
#include <cmfuncs.h>
#include <rtlfuncs.h>
+#include <setypes.h>
#include <umpnpmgr/sysguid.h>
#include <wdmguid.h>
#include <cfgmgr32.h>
+#include <regstr.h>
+#include <userenv.h>
#include <rpc.h>
#include <rpcdce.h>
-#include "pnp_c.h"
+#include "pnp_s.h"
#define NDEBUG
#include <debug.h>
static HANDLE hUserToken = NULL;
static HANDLE hInstallEvent = NULL;
+static HANDLE hNoPendingInstalls = NULL;
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+static SLIST_HEADER DeviceInstallListHead;
+#else
+static LIST_ENTRY DeviceInstallListHead;
+#endif
+static HANDLE hDeviceInstallListNotEmpty;
+
+typedef struct
+{
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+ SLIST_ENTRY ListEntry;
+#else
+ LIST_ENTRY ListEntry;
+#endif
+ WCHAR DeviceIds[1];
+} DeviceInstallParams;
/* FUNCTIONS *****************************************************************/
{
RPC_STATUS Status;
+ UNREFERENCED_PARAMETER(lpParameter);
+
DPRINT("RpcServerThread() called\n");
Status = RpcServerUseProtseqEpW(L"ncacn_np",
return 0;
}
+ /* ROS HACK (this should never happen...) */
+ DPRINT1("*** Other devices won't be installed correctly. If something\n");
+ DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
+
DPRINT("RpcServerThread() done\n");
return 0;
}
-void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
+void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}
}
+/* Function 0 */
+DWORD PNP_Disconnect(
+ handle_t hBinding)
+{
+ UNREFERENCED_PARAMETER(hBinding);
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 1 */
+DWORD PNP_Connect(
+ handle_t hBinding)
+{
+ UNREFERENCED_PARAMETER(hBinding);
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
/* Function 2 */
-CONFIGRET
-PNP_GetVersion(handle_t BindingHandle,
- unsigned short *Version)
+DWORD PNP_GetVersion(
+ handle_t hBinding,
+ WORD *pVersion)
{
- *Version = 0x0400;
+ UNREFERENCED_PARAMETER(hBinding);
+
+ *pVersion = 0x0400;
return CR_SUCCESS;
}
/* Function 3 */
-CONFIGRET
-PNP_GetGlobalState(handle_t BindingHandle,
- unsigned long *State,
- unsigned long Flags)
+DWORD PNP_GetGlobalState(
+ handle_t hBinding,
+ DWORD *pulState,
+ DWORD ulFlags)
{
- *State = CM_GLOBAL_STATE_CAN_DO_UI | CM_GLOBAL_STATE_SERVICES_AVAILABLE;
+ UNREFERENCED_PARAMETER(hBinding);
+ UNREFERENCED_PARAMETER(ulFlags);
+
+ *pulState = CM_GLOBAL_STATE_CAN_DO_UI | CM_GLOBAL_STATE_SERVICES_AVAILABLE;
return CR_SUCCESS;
}
/* Function 4 */
-CONFIGRET
-PNP_InitDetection(handle_t BindingHandle)
+DWORD PNP_InitDetection(
+ handle_t hBinding)
{
+ UNREFERENCED_PARAMETER(hBinding);
+
DPRINT("PNP_InitDetection() called\n");
return CR_SUCCESS;
}
/* Function 5 */
-CONFIGRET
-PNP_ReportLogOn(handle_t BindingHandle,
- unsigned long Admin,
- unsigned long ProcessId)
+DWORD PNP_ReportLogOn(
+ handle_t hBinding,
+ BOOL Admin,
+ DWORD ProcessId)
{
+ DWORD ReturnValue = CR_FAILURE;
HANDLE hProcess;
- DPRINT1("PNP_ReportLogOn(%lu, %lu) called\n", Admin, ProcessId);
+ UNREFERENCED_PARAMETER(hBinding);
+ UNREFERENCED_PARAMETER(Admin);
+
+ DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin, ProcessId);
/* Get the users token */
- hProcess = OpenProcess(PROCESS_ALL_ACCESS,
- TRUE,
- ProcessId);
- if (hProcess != NULL)
+ hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, ProcessId);
+
+ if(!hProcess)
{
- if (hUserToken != NULL)
- {
- CloseHandle(hUserToken);
- hUserToken = NULL;
- }
+ DPRINT1("OpenProcess failed with error %u\n", GetLastError());
+ goto cleanup;
+ }
- OpenProcessToken(hProcess,
- TOKEN_ALL_ACCESS,
- &hUserToken);
- CloseHandle(hProcess);
+ if (hUserToken)
+ {
+ CloseHandle(hUserToken);
+ hUserToken = NULL;
+ }
+
+ if(!OpenProcessToken(hProcess, TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY, &hUserToken))
+ {
+ DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
+ goto cleanup;
}
/* Trigger the installer thread */
- if (hInstallEvent != NULL)
+ if (hInstallEvent)
SetEvent(hInstallEvent);
- return CR_SUCCESS;
+ ReturnValue = CR_SUCCESS;
+
+cleanup:
+ if(hProcess)
+ CloseHandle(hProcess);
+
+ return ReturnValue;
}
/* Function 6 */
-CONFIGRET
-PNP_ValidateDeviceInstance(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long Flags)
+DWORD PNP_ValidateDeviceInstance(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulFlags)
{
CONFIGRET ret = CR_SUCCESS;
- HKEY hEnumKey = NULL;
HKEY hDeviceKey = NULL;
- DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
- DeviceInstance, Flags);
+ UNREFERENCED_PARAMETER(hBinding);
+ UNREFERENCED_PARAMETER(ulFlags);
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- L"System\\CurrentControlSet\\Enum",
- 0,
- KEY_ALL_ACCESS,
- &hEnumKey))
- {
- DPRINT("Could not open the Enum Key!\n");
- ret = CR_FAILURE;
- goto Done;
- }
+ DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
+ pDeviceID, ulFlags);
if (RegOpenKeyExW(hEnumKey,
- DeviceInstance,
+ pDeviceID,
0,
KEY_READ,
&hDeviceKey))
if (hDeviceKey != NULL)
RegCloseKey(hDeviceKey);
- if (hEnumKey != NULL)
- RegCloseKey(hEnumKey);
-
DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret);
return ret;
/* Function 7 */
-CONFIGRET
-PNP_GetRootDeviceInstance(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long Length)
+DWORD PNP_GetRootDeviceInstance(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ PNP_RPC_STRING_LEN ulLength)
{
CONFIGRET ret = CR_SUCCESS;
+ UNREFERENCED_PARAMETER(hBinding);
+
DPRINT("PNP_GetRootDeviceInstance() called\n");
- if (Length < lstrlenW(szRootDeviceId) + 1)
+ if (!pDeviceID)
+ {
+ ret = CR_INVALID_POINTER;
+ goto Done;
+ }
+ if (ulLength < lstrlenW(szRootDeviceId) + 1)
{
ret = CR_BUFFER_SMALL;
goto Done;
}
- lstrcpyW(DeviceInstance,
+ lstrcpyW(pDeviceID,
szRootDeviceId);
Done:
/* Function 8 */
-CONFIGRET
-PNP_GetRelatedDeviceInstance(handle_t BindingHandle,
- unsigned long Relationship,
- wchar_t *DeviceId,
- wchar_t *RelatedDeviceId,
- unsigned long Length,
- unsigned long Flags)
+DWORD PNP_GetRelatedDeviceInstance(
+ handle_t hBinding,
+ DWORD ulRelationship,
+ LPWSTR pDeviceID,
+ LPWSTR pRelatedDeviceId,
+ PNP_RPC_STRING_LEN *pulLength,
+ DWORD ulFlags)
{
PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData;
CONFIGRET ret = CR_SUCCESS;
NTSTATUS Status;
+ UNREFERENCED_PARAMETER(hBinding);
+ UNREFERENCED_PARAMETER(ulFlags);
+
DPRINT("PNP_GetRelatedDeviceInstance() called\n");
- DPRINT(" Relationship %ld\n", Relationship);
- DPRINT(" DeviceId %S\n", DeviceId);
+ DPRINT(" Relationship %ld\n", ulRelationship);
+ DPRINT(" DeviceId %S\n", pDeviceID);
RtlInitUnicodeString(&PlugPlayData.TargetDeviceInstance,
- DeviceId);
+ pDeviceID);
- PlugPlayData.Relation = Relationship;
+ PlugPlayData.Relation = ulRelationship;
- PlugPlayData.RelatedDeviceInstanceLength = Length;
- PlugPlayData.RelatedDeviceInstance = RelatedDeviceId;
+ PlugPlayData.RelatedDeviceInstanceLength = *pulLength;
+ PlugPlayData.RelatedDeviceInstance = pRelatedDeviceId;
Status = NtPlugPlayControl(PlugPlayControlGetRelatedDevice,
(PVOID)&PlugPlayData,
/* Function 9 */
-CONFIGRET
-PNP_EnumerateSubKeys(handle_t BindingHandle,
- unsigned long Branch,
- unsigned long Index,
- wchar_t *Buffer,
- unsigned long Length,
- unsigned long *RequiredLength,
- DWORD Flags)
+DWORD PNP_EnumerateSubKeys(
+ handle_t hBinding,
+ DWORD ulBranch,
+ DWORD ulIndex,
+ LPWSTR Buffer,
+ PNP_RPC_STRING_LEN ulLength,
+ PNP_RPC_STRING_LEN *pulRequiredLen,
+ DWORD ulFlags)
{
CONFIGRET ret = CR_SUCCESS;
HKEY hKey;
DWORD dwError;
+ UNREFERENCED_PARAMETER(hBinding);
+ UNREFERENCED_PARAMETER(ulFlags);
+
DPRINT("PNP_EnumerateSubKeys() called\n");
- switch (Branch)
+ switch (ulBranch)
{
- case PNP_BRANCH_ENUM:
+ case PNP_ENUMERATOR_SUBKEYS:
hKey = hEnumKey;
break;
- case PNP_BRANCH_CLASS:
+ case PNP_CLASS_SUBKEYS:
hKey = hClassKey;
break;
return CR_FAILURE;
}
- *RequiredLength = Length;
+ *pulRequiredLen = ulLength;
dwError = RegEnumKeyExW(hKey,
- Index,
+ ulIndex,
Buffer,
- RequiredLength,
+ pulRequiredLen,
NULL,
NULL,
NULL,
}
else
{
- (*RequiredLength)++;
+ (*pulRequiredLen)++;
}
DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret);
}
-/* Function 11 */
-CONFIGRET
-PNP_GetDeviceListSize(handle_t BindingHandle,
- wchar_t *Filter,
- unsigned long *Length,
- DWORD Flags)
+/* Function 10 */
+DWORD PNP_GetDeviceList(
+ handle_t hBinding,
+ LPWSTR pszFilter,
+ LPWSTR Buffer,
+ PNP_RPC_STRING_LEN *pulLength,
+ DWORD ulFlags)
{
- DPRINT("PNP_GetDeviceListSize() called\n");
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
- /* FIXME */
- *Length = 2;
- return CR_SUCCESS;
+/* Function 11 */
+DWORD PNP_GetDeviceListSize(
+ handle_t hBinding,
+ LPWSTR pszFilter,
+ PNP_RPC_BUFFER_SIZE *pulLen,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
}
/* Function 12 */
-CONFIGRET
-PNP_GetDepth(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long *Depth,
- DWORD Flags)
+DWORD PNP_GetDepth(
+ handle_t hBinding,
+ LPWSTR pszDeviceID,
+ DWORD *pulDepth,
+ DWORD ulFlags)
{
PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData;
CONFIGRET ret = CR_SUCCESS;
NTSTATUS Status;
+ UNREFERENCED_PARAMETER(hBinding);
+ UNREFERENCED_PARAMETER(ulFlags);
+
DPRINT("PNP_GetDepth() called\n");
RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
- DeviceInstance);
+ pszDeviceID);
Status = NtPlugPlayControl(PlugPlayControlGetDeviceDepth,
(PVOID)&PlugPlayData,
sizeof(PLUGPLAY_CONTROL_DEPTH_DATA));
if (NT_SUCCESS(Status))
{
- *Depth = PlugPlayData.Depth;
+ *pulDepth = PlugPlayData.Depth;
}
else
{
/* Function 13 */
-CONFIGRET
-PNP_GetDeviceRegProp(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long Property,
- unsigned long *DataType,
- char *Buffer,
- unsigned long *TransferLen,
- unsigned long *Length,
- DWORD Flags)
+DWORD PNP_GetDeviceRegProp(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulProperty,
+ DWORD *pulRegDataType,
+ BYTE *Buffer,
+ PNP_PROP_SIZE *pulTransferLen,
+ PNP_PROP_SIZE *pulLength,
+ DWORD ulFlags)
{
PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData;
CONFIGRET ret = CR_SUCCESS;
HKEY hKey = 0;
NTSTATUS Status;
+ UNREFERENCED_PARAMETER(hBinding);
+ UNREFERENCED_PARAMETER(ulFlags);
+
DPRINT("PNP_GetDeviceRegProp() called\n");
- switch (Property)
+ switch (ulProperty)
{
case CM_DRP_DEVICEDESC:
lpValueName = L"DeviceDesc";
{
/* Retrieve information from the Registry */
if (RegOpenKeyExW(hEnumKey,
- DeviceInstance,
+ pDeviceID,
0,
KEY_ALL_ACCESS,
&hKey))
if (RegQueryValueExW(hKey,
lpValueName,
NULL,
- DataType,
- (LPBYTE)Buffer,
- Length))
+ pulRegDataType,
+ Buffer,
+ pulLength))
ret = CR_REGISTRY_ERROR;
/* FIXME: Check buffer size */
{
/* Retrieve information from the Device Node */
RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
- DeviceInstance);
+ pDeviceID);
PlugPlayData.Buffer = Buffer;
- PlugPlayData.BufferSize = *TransferLen;
+ PlugPlayData.BufferSize = *pulTransferLen;
- switch (Property)
+ switch (ulProperty)
{
#if 0
case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME:
case CM_DRP_BUSNUMBER:
PlugPlayData.Property = DevicePropertyBusNumber;
break;
+#endif
case CM_DRP_ENUMERATOR_NAME:
- PlugPlayData.Property = DevicePropertyEnumeratorName;
+ PlugPlayData.Property = 15; //DevicePropertyEnumeratorName;
break;
-#endif
default:
return CR_INVALID_PROPERTY;
sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA));
if (NT_SUCCESS(Status))
{
- *Length = PlugPlayData.BufferSize;
+ *pulLength = PlugPlayData.BufferSize;
}
else
{
/* Function 14 */
-CONFIGRET
-PNP_SetDeviceRegProp(handle_t BindingHandle,
- wchar_t *DeviceId,
- unsigned long Property,
- unsigned long DataType,
- char *Buffer,
- unsigned long Length,
- unsigned long Flags)
+DWORD PNP_SetDeviceRegProp(
+ handle_t hBinding,
+ LPWSTR pDeviceId,
+ DWORD ulProperty,
+ DWORD ulDataType,
+ BYTE *Buffer,
+ PNP_PROP_SIZE ulLength,
+ DWORD ulFlags)
{
CONFIGRET ret = CR_SUCCESS;
LPWSTR lpValueName = NULL;
HKEY hKey = 0;
+ UNREFERENCED_PARAMETER(hBinding);
+ UNREFERENCED_PARAMETER(ulFlags);
+
DPRINT("PNP_SetDeviceRegProp() called\n");
- DPRINT("DeviceId: %S\n", DeviceId);
- DPRINT("Property: %lu\n", Property);
- DPRINT("DataType: %lu\n", DataType);
- DPRINT("Length: %lu\n", Length);
+ DPRINT("DeviceId: %S\n", pDeviceId);
+ DPRINT("Property: %lu\n", ulProperty);
+ DPRINT("DataType: %lu\n", ulDataType);
+ DPRINT("Length: %lu\n", ulLength);
- switch (Property)
+ switch (ulProperty)
{
case CM_DRP_DEVICEDESC:
lpValueName = L"DeviceDesc";
DPRINT("Value name: %S\n", lpValueName);
if (RegOpenKeyExW(hEnumKey,
- DeviceId,
+ pDeviceId,
0,
- KEY_ALL_ACCESS,
+ KEY_ALL_ACCESS, /* FIXME: so much? */
&hKey))
return CR_INVALID_DEVNODE;
- if (Length == 0)
+ if (ulLength == 0)
{
if (RegDeleteValueW(hKey,
lpValueName))
if (RegSetValueExW(hKey,
lpValueName,
0,
- DataType,
- (const BYTE*)Buffer,
- Length))
+ ulDataType,
+ Buffer,
+ ulLength))
ret = CR_REGISTRY_ERROR;
}
/* Function 15 */
-CONFIGRET
-PNP_GetClassInstance(handle_t BindingHandle,
- wchar_t *DeviceId, /* in */
- wchar_t *Buffer, /* out */
- unsigned long Length)
+DWORD PNP_GetClassInstance(
+ handle_t hBinding,
+ LPWSTR pDeviceId,
+ LPWSTR pszClassInstance,
+ PNP_RPC_STRING_LEN ulLength)
{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT("PNP_Get_Class_Instance() called\n");
-
- DPRINT("PNP_Get_Class_Instance() done (returns %lx)\n", ret);
-
- return ret;
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
}
/* Function 16 */
-CONFIGRET
-PNP_CreateKey(handle_t BindingHandle,
- wchar_t *SubKey,
- unsigned long samDesired,
- unsigned long Flags)
+DWORD PNP_CreateKey(
+ handle_t hBinding,
+ LPWSTR pszSubKey,
+ DWORD samDesired,
+ DWORD ulFlags)
{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT("PNP_CreateKey() called\n");
-
- DPRINT("PNP_CreateKey() done (returns %lx)\n", ret);
-
- return ret;
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
}
/* Function 17 */
-CONFIGRET
-PNP_DeleteRegistryKey(handle_t BindingHandle,
- wchar_t *DeviceId,
- wchar_t *ParentKey,
- wchar_t *ChildKey,
- unsigned long Flags)
+DWORD PNP_DeleteRegistryKey(
+ handle_t hBinding,
+ LPWSTR pszDeviceID,
+ LPWSTR pszParentKey,
+ LPWSTR pszChildKey,
+ DWORD ulFlags)
{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT("PNP_DeleteRegistryKey() called\n");
-
- DPRINT("PNP_DeleteRegistryKey() done (returns %lx)\n", ret);
-
- return ret;
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
}
/* Function 18 */
-#if 0
-CONFIGRET
-PNP_GetClassCount(handle_t BindingHandle,
- unsigned long *ClassCount,
- unsigned long Flags)
+DWORD PNP_GetClassCount(
+ handle_t hBinding,
+ DWORD *pulClassCount,
+ DWORD ulFlags)
{
- HANDLE hKey = NULL;
+ HKEY hKey;
DWORD dwError;
+ UNREFERENCED_PARAMETER(hBinding);
+ UNREFERENCED_PARAMETER(ulFlags);
+
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- pszRegPathClass,
+ REGSTR_PATH_CLASS,
0,
KEY_QUERY_VALUE,
&hKey);
NULL,
NULL,
NULL,
- &ClassCount,
+ pulClassCount,
NULL,
NULL,
NULL,
return CR_SUCCESS;
}
-#endif
/* Function 19 */
-CONFIGRET
-PNP_GetClassName(handle_t BindingHandle,
- wchar_t *ClassGuid,
- wchar_t *Buffer,
- unsigned long *Length,
- unsigned long Flags)
+DWORD PNP_GetClassName(
+ handle_t hBinding,
+ LPWSTR pszClassGuid,
+ LPWSTR Buffer,
+ PNP_RPC_STRING_LEN *pulLength,
+ DWORD ulFlags)
{
WCHAR szKeyName[MAX_PATH];
CONFIGRET ret = CR_SUCCESS;
- HKEY hKey = NULL;
- ULONG ulSize;
+ HKEY hKey;
+ DWORD dwSize;
+
+ UNREFERENCED_PARAMETER(hBinding);
+ UNREFERENCED_PARAMETER(ulFlags);
DPRINT("PNP_GetClassName() called\n");
- lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class");
- lstrcatW(szKeyName, L"\\");
- if(lstrlenW(ClassGuid) < sizeof(szKeyName)/sizeof(WCHAR)-lstrlenW(szKeyName))
- lstrcatW(szKeyName, ClassGuid);
+ lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class\\");
+ if(lstrlenW(pszClassGuid) + 1 < sizeof(szKeyName)/sizeof(WCHAR)-(lstrlenW(szKeyName) * sizeof(WCHAR)))
+ lstrcatW(szKeyName, pszClassGuid);
else return CR_INVALID_DATA;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
&hKey))
return CR_REGISTRY_ERROR;
- ulSize = *Length * sizeof(WCHAR);
+ dwSize = *pulLength * sizeof(WCHAR);
if (RegQueryValueExW(hKey,
L"Class",
NULL,
NULL,
(LPBYTE)Buffer,
- &ulSize))
+ &dwSize))
{
- *Length = 0;
+ *pulLength = 0;
ret = CR_REGISTRY_ERROR;
}
else
{
- *Length = ulSize / sizeof(WCHAR);
+ *pulLength = dwSize / sizeof(WCHAR);
}
RegCloseKey(hKey);
/* Function 20 */
-CONFIGRET
-PNP_DeleteClassKey(handle_t BindingHandle,
- wchar_t *ClassGuid,
- unsigned long Flags)
+DWORD PNP_DeleteClassKey(
+ handle_t hBinding,
+ LPWSTR pszClassGuid,
+ DWORD ulFlags)
{
CONFIGRET ret = CR_SUCCESS;
- DPRINT("PNP_GetClassName(%S, %lx) called\n", ClassGuid, Flags);
+ UNREFERENCED_PARAMETER(hBinding);
- if (Flags & CM_DELETE_CLASS_SUBKEYS)
+ DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid, ulFlags);
+
+ if (ulFlags & CM_DELETE_CLASS_SUBKEYS)
{
- if (RegDeleteTreeW(hClassKey, ClassGuid) != ERROR_SUCCESS)
+ if (RegDeleteTreeW(hClassKey, pszClassGuid) != ERROR_SUCCESS)
ret = CR_REGISTRY_ERROR;
}
else
{
- if (RegDeleteKeyW(hClassKey, ClassGuid) != ERROR_SUCCESS)
+ if (RegDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS)
ret = CR_REGISTRY_ERROR;
}
}
+/* Function 21 */
+DWORD PNP_GetInterfaceDeviceAlias(
+ handle_t hBinding,
+ LPWSTR pszInterfaceDevice,
+ GUID *AliasInterfaceGuid,
+ LPWSTR pszAliasInterfaceDevice,
+ PNP_RPC_STRING_LEN *pulLength,
+ PNP_RPC_STRING_LEN *pulTransferLen,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 22 */
+DWORD PNP_GetInterfaceDeviceList(
+ handle_t hBinding,
+ GUID *InterfaceGuid,
+ LPWSTR pszDeviceID,
+ BYTE *Buffer,
+ PNP_RPC_BUFFER_SIZE *pulLength,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 23 */
+DWORD PNP_GetInterfaceDeviceListSize(
+ handle_t hBinding,
+ PNP_RPC_BUFFER_SIZE *pulLen,
+ GUID *InterfaceGuid,
+ LPWSTR pszDeviceID,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 24 */
+DWORD PNP_RegisterDeviceClassAssociation(
+ handle_t hBinding,
+ LPWSTR pszDeviceID,
+ GUID *InterfaceGuid,
+ LPWSTR pszReference,
+ LPWSTR pszSymLink,
+ PNP_RPC_STRING_LEN *pulLength,
+ PNP_RPC_STRING_LEN *pulTransferLen,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 25 */
+DWORD PNP_UnregisterDeviceClassAssociation(
+ handle_t hBinding,
+ LPWSTR pszInterfaceDevice,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 26 */
+DWORD PNP_GetClassRegProp(
+ handle_t hBinding,
+ LPWSTR pszClassGuid,
+ DWORD ulProperty,
+ DWORD *pulRegDataType,
+ BYTE *Buffer,
+ PNP_RPC_STRING_LEN *pulTransferLen,
+ PNP_RPC_STRING_LEN *pulLength,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 27 */
+DWORD PNP_SetClassRegProp(
+ handle_t hBinding,
+ LPWSTR *pszClassGuid,
+ DWORD ulProperty,
+ DWORD ulDataType,
+ BYTE *Buffer,
+ PNP_PROP_SIZE ulLength,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
/* Function 28 */
-CONFIGRET
-PNP_CreateDevInst(handle_t BindingHandle,
- wchar_t *DeviceId, /* [in, out, string, size_is(Length)] */
- wchar_t *ParentDeviceId, /* [in, string] */
- unsigned long Length, /* [in] */
- unsigned long Flags) /* [in] */
+DWORD PNP_CreateDevInst(
+ handle_t hBinding,
+ LPWSTR pszDeviceID,
+ LPWSTR pszParentDeviceID,
+ PNP_RPC_STRING_LEN ulLength,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+static CONFIGRET
+MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination,
+ LPWSTR pszDeviceInstanceSource)
+{
+ DPRINT("MoveDeviceInstance: not implemented\n");
+ /* FIXME */
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+static CONFIGRET
+SetupDeviceInstance(LPWSTR pszDeviceInstance,
+ DWORD ulFlags)
+{
+ DPRINT("SetupDeviceInstance: not implemented\n");
+ /* FIXME */
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+static CONFIGRET
+EnableDeviceInstance(LPWSTR pszDeviceInstance)
{
- CONFIGRET ret = CR_CALL_NOT_IMPLEMENTED;
+ PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData;
+ CONFIGRET ret = CR_SUCCESS;
+ NTSTATUS Status;
- DPRINT1("PNP_CreateDevInst() called\n");
+ DPRINT("Enable device instance\n");
- DPRINT1("PNP_CreateDevInst() done (returns %lx)\n", ret);
+ RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, pszDeviceInstance);
+ Status = NtPlugPlayControl(PlugPlayControlResetDevice, &ResetDeviceData, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA));
+ if (!NT_SUCCESS(Status))
+ ret = NtStatusToCrError(Status);
return ret;
}
+static CONFIGRET
+DisableDeviceInstance(LPWSTR pszDeviceInstance)
+{
+ DPRINT("DisableDeviceInstance: not implemented\n");
+ /* FIXME */
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+static CONFIGRET
+ReenumerateDeviceInstance(LPWSTR pszDeviceInstance)
+{
+ DPRINT("ReenumerateDeviceInstance: not implemented\n");
+ /* FIXME */
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
/* Function 29 */
-CONFIGRET
-PNP_DeviceInstanceAction(handle_t BindingHandle,
- unsigned long MajorAction,
- unsigned long MinorAction,
- wchar_t *DeviceInstance1,
- wchar_t *DeviceInstance2)
+DWORD PNP_DeviceInstanceAction(
+ handle_t hBinding,
+ DWORD ulAction,
+ DWORD ulFlags,
+ LPWSTR pszDeviceInstance1,
+ LPWSTR pszDeviceInstance2)
{
CONFIGRET ret = CR_SUCCESS;
+ UNREFERENCED_PARAMETER(hBinding);
+
DPRINT("PNP_DeviceInstanceAction() called\n");
- switch (MajorAction)
+ switch (ulAction)
{
- case 2:
- DPRINT("Move device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
+ case PNP_DEVINST_MOVE:
+ ret = MoveDeviceInstance(pszDeviceInstance1,
+ pszDeviceInstance2);
break;
- case 3:
- DPRINT("Setup device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
+ case PNP_DEVINST_SETUP:
+ ret = SetupDeviceInstance(pszDeviceInstance1,
+ ulFlags);
break;
- case 4:
- DPRINT("Enable device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
+ case PNP_DEVINST_ENABLE:
+ ret = EnableDeviceInstance(pszDeviceInstance1);
break;
- case 5:
- DPRINT("Disable device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
+ case PNP_DEVINST_DISABLE:
+ ret = DisableDeviceInstance(pszDeviceInstance1);
break;
- case 7:
- DPRINT("Reenumerate device instance\n");
- /* FIXME */
- ret = CR_CALL_NOT_IMPLEMENTED;
+ case PNP_DEVINST_REENUMERATE:
+ ret = ReenumerateDeviceInstance(pszDeviceInstance1);
break;
default:
- DPRINT1("Unknown function %lu\n", MajorAction);
+ DPRINT1("Unknown device action %lu: not implemented\n", ulAction);
ret = CR_CALL_NOT_IMPLEMENTED;
}
/* Function 30 */
-CONFIGRET
-PNP_GetDeviceStatus(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long *pStatus,
- unsigned long *pProblem,
- DWORD Flags)
+DWORD PNP_GetDeviceStatus(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD *pulStatus,
+ DWORD *pulProblem,
+ DWORD ulFlags)
{
PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
CONFIGRET ret = CR_SUCCESS;
NTSTATUS Status;
+ UNREFERENCED_PARAMETER(hBinding);
+ UNREFERENCED_PARAMETER(ulFlags);
+
DPRINT("PNP_GetDeviceStatus() called\n");
RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
- DeviceInstance);
+ pDeviceID);
PlugPlayData.Operation = 0; /* Get status */
Status = NtPlugPlayControl(PlugPlayControlDeviceStatus,
sizeof(PLUGPLAY_CONTROL_STATUS_DATA));
if (NT_SUCCESS(Status))
{
- *pStatus = PlugPlayData.DeviceStatus;
- *pProblem = PlugPlayData.DeviceProblem;
+ *pulStatus = PlugPlayData.DeviceStatus;
+ *pulProblem = PlugPlayData.DeviceProblem;
}
else
{
/* Function 31 */
-CONFIGRET
-PNP_SetDeviceProblem(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- unsigned long Problem,
- DWORD Flags)
+DWORD PNP_SetDeviceProblem(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulProblem,
+ DWORD ulFlags)
{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT1("PNP_SetDeviceProblem() called\n");
-
- /* FIXME */
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
- DPRINT1("PNP_SetDeviceProblem() done (returns %lx)\n", ret);
- return ret;
+/* Function 32 */
+DWORD PNP_DisableDevInst(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ PPNP_VETO_TYPE pVetoType,
+ LPWSTR pszVetoName,
+ DWORD ulNameLength,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
}
-
/* Function 33 */
-CONFIGRET
-PNP_UninstallDevInst(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- DWORD Flags)
+DWORD PNP_UninstallDevInst(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulFlags)
{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT1("PNP_UninstallDevInst() called\n");
-
- /* FIXME */
-
- DPRINT1("PNP_UninstallDevInst() done (returns %lx)\n", ret);
-
- return ret;
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
}
while (*lpPtr != 0)
{
dwLength = wcslen(lpPtr);
- if (!_wcsicmp(lpPtr, lpDeviceId))
+ if (0 == _wcsicmp(lpPtr, lpDeviceId))
return TRUE;
lpPtr += (dwLength + 1);
/* Function 34 */
-CONFIGRET
-PNP_AddID(handle_t BindingHandle,
- wchar_t *DeviceInstance,
- wchar_t *DeviceId,
- DWORD Flags)
+DWORD PNP_AddID(
+ handle_t hBinding,
+ LPWSTR pszDeviceID,
+ LPWSTR pszID,
+ DWORD ulFlags)
{
CONFIGRET ret = CR_SUCCESS;
HKEY hDeviceKey;
LPWSTR pszSubKey;
DWORD dwDeviceIdListSize;
- WCHAR szDeviceIdList[512];
+ DWORD dwNewDeviceIdSize;
+ WCHAR * pszDeviceIdList = NULL;
+
+ UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_AddID() called\n");
- DPRINT(" DeviceInstance: %S\n", DeviceInstance);
- DPRINT(" DeviceId: %S\n", DeviceId);
- DPRINT(" Flags: %lx\n", Flags);
+ DPRINT(" DeviceInstance: %S\n", pszDeviceID);
+ DPRINT(" DeviceId: %S\n", pszID);
+ DPRINT(" Flags: %lx\n", ulFlags);
if (RegOpenKeyExW(hEnumKey,
- DeviceInstance,
+ pszDeviceID,
0,
KEY_QUERY_VALUE | KEY_SET_VALUE,
&hDeviceKey) != ERROR_SUCCESS)
return CR_INVALID_DEVNODE;
}
- pszSubKey = (Flags & CM_ADD_ID_COMPATIBLE) ? L"CompatibleIDs" : L"HardwareID";
+ pszSubKey = (ulFlags & CM_ADD_ID_COMPATIBLE) ? L"CompatibleIDs" : L"HardwareID";
+
+ if (RegQueryValueExW(hDeviceKey,
+ pszSubKey,
+ NULL,
+ NULL,
+ NULL,
+ &dwDeviceIdListSize) != ERROR_SUCCESS)
+ {
+ DPRINT("Failed to query the desired ID string!\n");
+ ret = CR_REGISTRY_ERROR;
+ goto Done;
+ }
+
+ dwNewDeviceIdSize = lstrlenW(pszDeviceID);
+ if (!dwNewDeviceIdSize)
+ {
+ ret = CR_INVALID_POINTER;
+ goto Done;
+ }
+
+ dwDeviceIdListSize += (dwNewDeviceIdSize + 2) * sizeof(WCHAR);
+
+ pszDeviceIdList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDeviceIdListSize);
+ if (!pszDeviceIdList)
+ {
+ DPRINT("Failed to allocate memory for the desired ID string!\n");
+ ret = CR_OUT_OF_MEMORY;
+ goto Done;
+ }
- dwDeviceIdListSize = 512 * sizeof(WCHAR);
if (RegQueryValueExW(hDeviceKey,
pszSubKey,
NULL,
NULL,
- (LPBYTE)szDeviceIdList,
+ (LPBYTE)pszDeviceIdList,
&dwDeviceIdListSize) != ERROR_SUCCESS)
{
DPRINT("Failed to query the desired ID string!\n");
}
/* Check whether the device ID is already in use */
- if (CheckForDeviceId(szDeviceIdList, DeviceId))
+ if (CheckForDeviceId(pszDeviceIdList, pszDeviceID))
{
DPRINT("Device ID was found in the ID string!\n");
ret = CR_SUCCESS;
}
/* Append the Device ID */
- AppendDeviceId(szDeviceIdList, &dwDeviceIdListSize, DeviceId);
+ AppendDeviceId(pszDeviceIdList, &dwDeviceIdListSize, pszID);
if (RegSetValueExW(hDeviceKey,
pszSubKey,
0,
REG_MULTI_SZ,
- (LPBYTE)szDeviceIdList,
+ (LPBYTE)pszDeviceIdList,
dwDeviceIdListSize) != ERROR_SUCCESS)
{
DPRINT("Failed to set the desired ID string!\n");
Done:
RegCloseKey(hDeviceKey);
+ if (pszDeviceIdList)
+ HeapFree(GetProcessHeap(), 0, pszDeviceIdList);
DPRINT("PNP_AddID() done (returns %lx)\n", ret);
}
+/* Function 35 */
+DWORD PNP_RegisterDriver(
+ handle_t hBinding,
+ LPWSTR pszDeviceID,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 36 */
+DWORD PNP_QueryRemove(
+ handle_t hBinding,
+ LPWSTR pszDeviceID,
+ PPNP_VETO_TYPE pVetoType,
+ LPWSTR pszVetoName,
+ DWORD ulNameLength,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 37 */
+DWORD PNP_RequestDeviceEject(
+ handle_t hBinding,
+ LPWSTR pszDeviceID,
+ PPNP_VETO_TYPE pVetoType,
+ LPWSTR pszVetoName,
+ DWORD ulNameLength,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
/* Function 38 */
CONFIGRET
-PNP_IsDockStationPresent(handle_t BindingHandle,
- unsigned long *Present)
+PNP_IsDockStationPresent(handle_t hBinding,
+ BOOL *Present)
{
HKEY hKey;
DWORD dwType;
DWORD dwSize;
CONFIGRET ret = CR_SUCCESS;
+ UNREFERENCED_PARAMETER(hBinding);
+
DPRINT1("PNP_IsDockStationPresent() called\n");
*Present = FALSE;
/* Function 39 */
-CONFIGRET
-PNP_RequestEjectPC(handle_t BindingHandle)
+DWORD PNP_RequestEjectPC(
+ handle_t hBinding)
{
- CONFIGRET ret = CR_SUCCESS;
-
- DPRINT1("PNP_RequestEjectPC() called\n");
-
- ret = CR_FAILURE; /* FIXME */
-
- DPRINT1("PNP_RequestEjectPC() done (returns %lx)\n", ret);
-
- return ret;
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
}
/* Function 40 */
-CONFIGRET
-PNP_HwProfFlags(handle_t BindingHandle,
- unsigned long Action,
- wchar_t *DeviceId,
- unsigned long ProfileId,
- unsigned long *Value, // out
- unsigned long Flags)
+DWORD PNP_HwProfFlags(
+ handle_t hBinding,
+ DWORD ulAction,
+ LPWSTR pDeviceID,
+ DWORD ulConfig,
+ DWORD *pulValue,
+ PPNP_VETO_TYPE pVetoType,
+ LPWSTR pszVetoName,
+ DWORD ulNameLength,
+ DWORD ulFlags)
{
- CONFIGRET ret = CR_SUCCESS;
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
- DPRINT1("PNP_HwProfFlags() called\n");
- ret = CR_CALL_NOT_IMPLEMENTED; /* FIXME */
+/* Function 41 */
+DWORD PNP_GetHwProfInfo(
+ handle_t hBinding,
+ DWORD ulIndex,
+ HWPROFILEINFO *pHWProfileInfo,
+ DWORD ulProfileInfoSize,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
- DPRINT1("PNP_HwProfFlags() done (returns %lx)\n", ret);
- return ret;
+/* Function 42 */
+DWORD PNP_AddEmptyLogConf(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulPriority,
+ DWORD *pulLogConfTag,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 43 */
+DWORD PNP_FreeLogConf(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulLogConfType,
+ DWORD ulLogConfTag,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 44 */
+DWORD PNP_GetFirstLogConf(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulLogConfType,
+ DWORD *pulLogConfTag,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 45 */
+DWORD PNP_GetNextLogConf(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulLogConfType,
+ DWORD ulCurrentTag,
+ DWORD *pulNextTag,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 46 */
+DWORD PNP_GetLogConfPriority(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulType,
+ DWORD ulTag,
+ DWORD *pPriority,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 47 */
+DWORD PNP_AddResDes(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulLogConfTag,
+ DWORD ulLogConfType,
+ RESOURCEID ResourceID,
+ DWORD *pulResourceTag,
+ BYTE *ResourceData,
+ PNP_RPC_BUFFER_SIZE ResourceLen,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 48 */
+DWORD PNP_FreeResDes(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulLogConfTag,
+ DWORD ulLogConfType,
+ RESOURCEID ResourceID,
+ DWORD ulResourceTag,
+ DWORD *pulPreviousResType,
+ DWORD *pulPreviousResTag,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 49 */
+DWORD PNP_GetNextResDes(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulLogConfTag,
+ DWORD ulLogConfType,
+ RESOURCEID ResourceID,
+ DWORD ulResourceTag,
+ DWORD *pulNextResType,
+ DWORD *pulNextResTag,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 50 */
+DWORD PNP_GetResDesData(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulLogConfTag,
+ DWORD ulLogConfType,
+ RESOURCEID ResourceID,
+ DWORD ulResourceTag,
+ BYTE *Buffer,
+ PNP_RPC_BUFFER_SIZE BufferLen,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 51 */
+DWORD PNP_GetResDesDataSize(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulLogConfTag,
+ DWORD ulLogConfType,
+ RESOURCEID ResourceID,
+ DWORD ulResourceTag,
+ DWORD *pulSize,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 52 */
+DWORD PNP_ModifyResDes(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ DWORD ulLogConfTag,
+ DWORD ulLogConfType,
+ RESOURCEID CurrentResourceID,
+ RESOURCEID NewResourceID,
+ DWORD ulResourceTag,
+ BYTE *ResourceData,
+ PNP_RPC_BUFFER_SIZE ResourceLen,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 53 */
+DWORD PNP_DetectResourceConflict(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ RESOURCEID ResourceID,
+ BYTE *ResourceData,
+ PNP_RPC_BUFFER_SIZE ResourceLen,
+ BOOL *pbConflictDetected,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 54 */
+DWORD PNP_QueryResConfList(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ RESOURCEID ResourceID,
+ BYTE *ResourceData,
+ PNP_RPC_BUFFER_SIZE ResourceLen,
+ BYTE *Buffer,
+ PNP_RPC_BUFFER_SIZE BufferLen,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 55 */
+DWORD PNP_SetHwProf(
+ handle_t hBinding)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 56 */
+DWORD PNP_QueryArbitratorFreeData(
+ handle_t hBinding)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 57 */
+DWORD PNP_QueryArbitratorFreeSize(
+ handle_t hBinding)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
}
/* Function 58 */
CONFIGRET
-PNP_RunDetection(handle_t BindingHandle,
- unsigned long Flags)
+PNP_RunDetection(
+ handle_t hBinding,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 59 */
+DWORD PNP_RegisterNotification(
+ handle_t hBinding)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 60 */
+DWORD PNP_UnregisterNotification(
+ handle_t hBinding)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 61 */
+DWORD PNP_GetCustomDevProp(
+ handle_t hBinding,
+ LPWSTR pDeviceID,
+ LPWSTR CustomPropName,
+ DWORD *pulRegDataType,
+ BYTE *Buffer,
+ PNP_RPC_STRING_LEN *pulTransferLen,
+ PNP_RPC_STRING_LEN *pulLength,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 62 */
+DWORD PNP_GetVersionInternal(
+ handle_t hBinding,
+ WORD *pwVersion)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 63 */
+DWORD PNP_GetBlockedDriverInfo(
+ handle_t hBinding,
+ BYTE *Buffer,
+ PNP_RPC_BUFFER_SIZE *pulTransferLen,
+ PNP_RPC_BUFFER_SIZE *pulLength,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 64 */
+DWORD PNP_GetServerSideDeviceInstallFlags(
+ handle_t hBinding,
+ DWORD *pulSSDIFlags,
+ DWORD ulFlags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 65 */
+DWORD PNP_GetObjectPropKeys(
+ handle_t hBinding,
+ LPWSTR ObjectName,
+ DWORD ObjectType,
+ LPWSTR PropertyCultureName,
+ PNP_PROP_COUNT *PropertyCount,
+ PNP_PROP_COUNT *TransferLen,
+ DEVPROPKEY *PropertyKeys,
+ DWORD Flags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 66 */
+DWORD PNP_GetObjectProp(
+ handle_t hBinding,
+ LPWSTR ObjectName,
+ DWORD ObjectType,
+ LPWSTR PropertyCultureName,
+ const DEVPROPKEY *PropertyKey,
+ DEVPROPTYPE *PropertyType,
+ PNP_PROP_SIZE *PropertySize,
+ PNP_PROP_SIZE *TransferLen,
+ BYTE *PropertyBuffer,
+ DWORD Flags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 67 */
+DWORD PNP_SetObjectProp(
+ handle_t hBinding,
+ LPWSTR ObjectName,
+ DWORD ObjectType,
+ LPWSTR PropertyCultureName,
+ const DEVPROPKEY *PropertyKey,
+ DEVPROPTYPE PropertyType,
+ PNP_PROP_SIZE PropertySize,
+ BYTE *PropertyBuffer,
+ DWORD Flags)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 68 */
+DWORD PNP_InstallDevInst(
+ handle_t hBinding)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 69 */
+DWORD PNP_ApplyPowerSettings(
+ handle_t hBinding)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 70 */
+DWORD PNP_DriverStoreAddDriverPackage(
+ handle_t hBinding)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 71 */
+DWORD PNP_DriverStoreDeleteDriverPackage(
+ handle_t hBinding)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 72 */
+DWORD PNP_RegisterServiceNotification(
+ handle_t hBinding)
{
- DPRINT("PNP_RunDetection() called\n");
+ UNIMPLEMENTED;
return CR_CALL_NOT_IMPLEMENTED;
}
-typedef BOOL (WINAPI *PDEV_INSTALL_W)(HWND, HINSTANCE, LPCWSTR, INT);
+/* Function 73 */
+DWORD PNP_SetActiveService(
+ handle_t hBinding)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 74 */
+DWORD PNP_DeleteServiceDevices(
+ handle_t hBinding)
+{
+ UNIMPLEMENTED;
+ return CR_CALL_NOT_IMPLEMENTED;
+}
+
static BOOL
-InstallDevice(PCWSTR DeviceInstance, BOOL SetupIsActive)
+InstallDevice(PCWSTR DeviceInstance, BOOL ShowWizard)
{
PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
- HMODULE hNewDev = NULL;
- PDEV_INSTALL_W DevInstallW;
NTSTATUS Status;
BOOL DeviceInstalled = FALSE;
+ DWORD BytesWritten;
+ DWORD Value;
+ HANDLE hPipe = INVALID_HANDLE_VALUE;
+ LPVOID Environment = NULL;
+ PROCESS_INFORMATION ProcessInfo;
+ STARTUPINFOW StartupInfo;
+ UUID RandomUuid;
+
+ /* The following lengths are constant (see below), they cannot overflow */
+ WCHAR CommandLine[116];
+ WCHAR InstallEventName[73];
+ WCHAR PipeName[74];
+ WCHAR UuidString[39];
+
+ DPRINT("InstallDevice(%S, %d)\n", DeviceInstance, ShowWizard);
+
+ ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
DeviceInstance);
(PVOID)&PlugPlayData,
sizeof(PLUGPLAY_CONTROL_STATUS_DATA));
if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtPlugPlayControl('%S') failed with status 0x%08lx\n", DeviceInstance, Status);
return FALSE;
+ }
- if (PlugPlayData.DeviceStatus & DNF_STARTED || PlugPlayData.DeviceStatus & DNF_START_FAILED)
+ if ((PlugPlayData.DeviceStatus & (DNF_STARTED | DNF_START_FAILED)) != 0)
+ {
/* Device is already started, or disabled due to some problem. Don't install it */
+ DPRINT("No need to install '%S'\n", DeviceInstance);
return TRUE;
+ }
+
+ /* Create a random UUID for the named pipe */
+ UuidCreate(&RandomUuid);
+ swprintf(UuidString, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+ RandomUuid.Data1, RandomUuid.Data2, RandomUuid.Data3,
+ RandomUuid.Data4[0], RandomUuid.Data4[1], RandomUuid.Data4[2],
+ RandomUuid.Data4[3], RandomUuid.Data4[4], RandomUuid.Data4[5],
+ RandomUuid.Data4[6], RandomUuid.Data4[7]);
- /* Install device */
- SetEnvironmentVariable(L"USERPROFILE", L"."); /* FIXME: why is it needed? */
+ /* Create the named pipe */
+ wcscpy(PipeName, L"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
+ wcscat(PipeName, UuidString);
+ hPipe = CreateNamedPipeW(PipeName, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 512, 512, 0, NULL);
- hNewDev = LoadLibraryW(L"newdev.dll");
- if (!hNewDev)
+ if(hPipe == INVALID_HANDLE_VALUE)
+ {
+ DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
goto cleanup;
+ }
+
+ /* Launch rundll32 to call ClientSideInstallW */
+ wcscpy(CommandLine, L"rundll32.exe newdev.dll,ClientSideInstall ");
+ wcscat(CommandLine, PipeName);
- DevInstallW = (PDEV_INSTALL_W)GetProcAddress(hNewDev, (LPCSTR)"DevInstallW");
- if (!DevInstallW)
+ ZeroMemory(&StartupInfo, sizeof(StartupInfo));
+ StartupInfo.cb = sizeof(StartupInfo);
+
+ if(hUserToken)
+ {
+ /* newdev has to run under the environment of the current user */
+ if(!CreateEnvironmentBlock(&Environment, hUserToken, FALSE))
+ {
+ DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
+ goto cleanup;
+ }
+
+ if(!CreateProcessAsUserW(hUserToken, NULL, CommandLine, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, Environment, NULL, &StartupInfo, &ProcessInfo))
+ {
+ DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
+ goto cleanup;
+ }
+ }
+ else
+ {
+ /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
+
+ Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
+ (ShowWizard is only set to FALSE for these two modes) */
+ ASSERT(!ShowWizard);
+
+ if(!CreateProcessW(NULL, CommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo))
+ {
+ DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
+ goto cleanup;
+ }
+ }
+
+ /* Wait for the function to connect to our pipe */
+ if(!ConnectNamedPipe(hPipe, NULL))
+ {
+ DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
goto cleanup;
+ }
+
+ /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
+ wcscpy(InstallEventName, L"Global\\PNP_Device_Install_Event_0.");
+ wcscat(InstallEventName, UuidString);
+
+ Value = sizeof(InstallEventName);
+ WriteFile(hPipe, &Value, sizeof(Value), &BytesWritten, NULL);
+ WriteFile(hPipe, InstallEventName, Value, &BytesWritten, NULL);
+
+ /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
+ Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
+ WriteFile(hPipe, &ShowWizard, sizeof(ShowWizard), &BytesWritten, NULL);
+
+ Value = (wcslen(DeviceInstance) + 1) * sizeof(WCHAR);
+ WriteFile(hPipe, &Value, sizeof(Value), &BytesWritten, NULL);
+ WriteFile(hPipe, DeviceInstance, Value, &BytesWritten, NULL);
- if (!DevInstallW(NULL, NULL, DeviceInstance, SetupIsActive ? SW_HIDE : SW_SHOWNOACTIVATE))
+ /* Wait for newdev.dll to finish processing */
+ WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
+
+ /* The following check for success is probably not compatible to Windows, but should do its job */
+ if(!GetExitCodeProcess(ProcessInfo.hProcess, &Value))
+ {
+ DPRINT1("GetExitCodeProcess failed with error %u\n", GetLastError());
goto cleanup;
+ }
- DeviceInstalled = TRUE;
+ DeviceInstalled = Value;
cleanup:
- if (hNewDev != NULL)
- FreeLibrary(hNewDev);
+ if(hPipe != INVALID_HANDLE_VALUE)
+ CloseHandle(hPipe);
+
+ if(Environment)
+ DestroyEnvironmentBlock(Environment);
+
+ if(ProcessInfo.hProcess)
+ CloseHandle(ProcessInfo.hProcess);
+
+ if(ProcessInfo.hThread)
+ CloseHandle(ProcessInfo.hThread);
return DeviceInstalled;
}
+static LONG
+ReadRegSzKey(
+ IN HKEY hKey,
+ IN LPCWSTR pszKey,
+ OUT LPWSTR* pValue)
+{
+ LONG rc;
+ DWORD dwType;
+ DWORD cbData = 0;
+ LPWSTR Value;
+
+ if (!pValue)
+ return ERROR_INVALID_PARAMETER;
+
+ *pValue = NULL;
+ rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData);
+ if (rc != ERROR_SUCCESS)
+ return rc;
+ if (dwType != REG_SZ)
+ return ERROR_FILE_NOT_FOUND;
+ Value = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR));
+ if (!Value)
+ return ERROR_NOT_ENOUGH_MEMORY;
+ rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData);
+ if (rc != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(), 0, Value);
+ return rc;
+ }
+ /* NULL-terminate the string */
+ Value[cbData / sizeof(WCHAR)] = '\0';
+
+ *pValue = Value;
+ return ERROR_SUCCESS;
+}
+
+
static BOOL
SetupIsActive(VOID)
{
}
+static BOOL
+IsConsoleBoot(VOID)
+{
+ HKEY ControlKey = NULL;
+ LPWSTR SystemStartOptions = NULL;
+ LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */
+ BOOL ConsoleBoot = FALSE;
+ LONG rc;
+
+ rc = RegOpenKeyExW(
+ HKEY_LOCAL_MACHINE,
+ L"SYSTEM\\CurrentControlSet\\Control",
+ 0,
+ KEY_QUERY_VALUE,
+ &ControlKey);
+
+ rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions);
+ if (rc != ERROR_SUCCESS)
+ goto cleanup;
+
+ /* Check for CMDCONS in SystemStartOptions */
+ CurrentOption = SystemStartOptions;
+ while (CurrentOption)
+ {
+ NextOption = wcschr(CurrentOption, L' ');
+ if (NextOption)
+ *NextOption = L'\0';
+ if (_wcsicmp(CurrentOption, L"CONSOLE") == 0)
+ {
+ DPRINT("Found %S. Switching to console boot\n", CurrentOption);
+ ConsoleBoot = TRUE;
+ goto cleanup;
+ }
+ CurrentOption = NextOption ? NextOption + 1 : NULL;
+ }
+
+cleanup:
+ if (ControlKey != NULL)
+ RegCloseKey(ControlKey);
+ HeapFree(GetProcessHeap(), 0, SystemStartOptions);
+ return ConsoleBoot;
+}
+
+
+/* Loop to install all queued devices installations */
+static DWORD WINAPI
+DeviceInstallThread(LPVOID lpParameter)
+{
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+ PSLIST_ENTRY ListEntry;
+#else
+ PLIST_ENTRY ListEntry;
+#endif
+ DeviceInstallParams* Params;
+ BOOL showWizard;
+
+ UNREFERENCED_PARAMETER(lpParameter);
+
+ WaitForSingleObject(hInstallEvent, INFINITE);
+
+ showWizard = !SetupIsActive() && !IsConsoleBoot();
+
+ while (TRUE)
+ {
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+ ListEntry = InterlockedPopEntrySList(&DeviceInstallListHead);
+#else
+ if ((BOOL)IsListEmpty(&DeviceInstallListHead))
+ ListEntry = NULL;
+ else
+ ListEntry = RemoveHeadList(&DeviceInstallListHead);
+#endif
+ if (ListEntry == NULL)
+ {
+ SetEvent(hNoPendingInstalls);
+ WaitForSingleObject(hDeviceInstallListNotEmpty, INFINITE);
+ }
+ else
+ {
+ ResetEvent(hNoPendingInstalls);
+ Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry);
+ InstallDevice(Params->DeviceIds, showWizard);
+ }
+ }
+
+ return 0;
+}
+
+
static DWORD WINAPI
PnpEventThread(LPVOID lpParameter)
{
ULONG PnpEventSize;
NTSTATUS Status;
RPC_STATUS RpcStatus;
- BOOL setupActive;
+
+ UNREFERENCED_PARAMETER(lpParameter);
PnpEventSize = 0x1000;
PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize);
if (PnpEvent == NULL)
return ERROR_OUTOFMEMORY;
- setupActive = SetupIsActive();
-
for (;;)
{
DPRINT("Calling NtGetPlugPlayEvent()\n");
if (Status == STATUS_BUFFER_TOO_SMALL)
{
PnpEventSize += 0x400;
- PnpEvent = HeapReAlloc(GetProcessHeap(), 0, PnpEvent, PnpEventSize);
+ HeapFree(GetProcessHeap(), 0, PnpEvent);
+ PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize);
if (PnpEvent == NULL)
return ERROR_OUTOFMEMORY;
continue;
if (!NT_SUCCESS(Status))
{
- DPRINT("NtPlugPlayEvent() failed (Status %lx)\n", Status);
+ DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status);
break;
}
+ /* Process the pnp event */
DPRINT("Received PnP Event\n");
- if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
+ if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ENUMERATED, &RpcStatus))
+ {
+ DeviceInstallParams* Params;
+ DWORD len;
+ DWORD DeviceIdLength;
+
+ DPRINT("Device enumerated: %S\n", PnpEvent->TargetDevice.DeviceIds);
+
+ DeviceIdLength = lstrlenW(PnpEvent->TargetDevice.DeviceIds);
+ if (DeviceIdLength)
+ {
+ /* Queue device install (will be dequeued by DeviceInstallThread */
+ len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR);
+ Params = HeapAlloc(GetProcessHeap(), 0, len);
+ if (Params)
+ {
+ wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds);
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+ InterlockedPushEntrySList(&DeviceInstallListHead, &Params->ListEntry);
+#else
+ InsertTailList(&DeviceInstallListHead, &Params->ListEntry);
+#endif
+ SetEvent(hDeviceInstallListNotEmpty);
+ }
+ }
+ }
+ else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
{
- DPRINT("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds);
- InstallDevice(PnpEvent->TargetDevice.DeviceIds, setupActive);
+ DPRINT("Device arrival: %S\n", PnpEvent->TargetDevice.DeviceIds);
+ /* FIXME: ? */
}
else
{
- DPRINT1("Unknown event\n");
+ DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
+ PnpEvent->EventGuid.Data1, PnpEvent->EventGuid.Data2, PnpEvent->EventGuid.Data3,
+ PnpEvent->EventGuid.Data4[0], PnpEvent->EventGuid.Data4[1], PnpEvent->EventGuid.Data4[2],
+ PnpEvent->EventGuid.Data4[3], PnpEvent->EventGuid.Data4[4], PnpEvent->EventGuid.Data4[5],
+ PnpEvent->EventGuid.Data4[6], PnpEvent->EventGuid.Data4[7]);
}
- /* FIXME: Process the pnp event */
-
/* Dequeue the current pnp event and signal the next one */
NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0);
}
HANDLE hThread;
DWORD dwThreadId;
+ UNREFERENCED_PARAMETER(argc);
+ UNREFERENCED_PARAMETER(argv);
+
DPRINT("ServiceMain() called\n");
hThread = CreateThread(NULL,
if (hThread != NULL)
CloseHandle(hThread);
+ hThread = CreateThread(NULL,
+ 0,
+ DeviceInstallThread,
+ NULL,
+ 0,
+ &dwThreadId);
+ if (hThread != NULL)
+ CloseHandle(hThread);
+
DPRINT("ServiceMain() done\n");
}
int
-main(int argc, char *argv[])
+wmain(int argc, WCHAR *argv[])
{
+ BOOLEAN OldValue;
DWORD dwError;
+ UNREFERENCED_PARAMETER(argc);
+ UNREFERENCED_PARAMETER(argv);
+
DPRINT("Umpnpmgr: main() started\n");
- hInstallEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ /* We need this privilege for using CreateProcessAsUserW */
+ RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &OldValue);
+
+ hInstallEvent = CreateEvent(NULL, TRUE, SetupIsActive()/*FALSE*/, NULL);
if (hInstallEvent == NULL)
{
dwError = GetLastError();
return dwError;
}
+ hDeviceInstallListNotEmpty = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (hDeviceInstallListNotEmpty == NULL)
+ {
+ dwError = GetLastError();
+ DPRINT1("Could not create the Event! (Error %lu)\n", dwError);
+ return dwError;
+ }
+
+ hNoPendingInstalls = CreateEventW(NULL,
+ TRUE,
+ FALSE,
+ L"Global\\PnP_No_Pending_Install_Events");
+ if (hNoPendingInstalls == NULL)
+ {
+ dwError = GetLastError();
+ DPRINT1("Could not create the Event! (Error %lu)\n", dwError);
+ return dwError;
+ }
+
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+ InitializeSListHead(&DeviceInstallListHead);
+#else
+ InitializeListHead(&DeviceInstallListHead);
+#endif
+
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Enum",
0,