mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1696 lines
42 KiB
1696 lines
42 KiB
|
|
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
devnode.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the API routines that operate directly on device
|
|
instances (or DevNodes, in Win95 terminology).
|
|
|
|
|
|
CM_Create_DevNode
|
|
CM_Move_DevNode
|
|
CM_Setup_DevNode
|
|
CM_Disble_DevNode
|
|
CM_Enable_DevNode
|
|
CM_Get_DevNode_Status
|
|
CM_Reenumerate_DevNode
|
|
CM_Query_Remove_Subtree
|
|
CM_Remove_SubTree
|
|
CM_Add_ID
|
|
|
|
Author:
|
|
|
|
Paula Tomlinson (paulat) 6-20-1995
|
|
|
|
Environment:
|
|
|
|
User mode only.
|
|
|
|
Revision History:
|
|
|
|
6-Jun-1995 paulat
|
|
|
|
Creation and initial implementation.
|
|
|
|
--*/
|
|
|
|
|
|
//
|
|
// includes
|
|
//
|
|
#include "precomp.h"
|
|
#include "setupapi.h"
|
|
#include "spapip.h"
|
|
|
|
//
|
|
// Private prototypes
|
|
//
|
|
|
|
//
|
|
// global data
|
|
//
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Create_DevNode_ExW(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINSTID_W pDeviceID,
|
|
IN DEVINST dnParent,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine creates a new device instance in the hardware tree.
|
|
|
|
Parameters:
|
|
|
|
pdnDevNode Supplies the address of the variable that receives a handle
|
|
to the new device instance.
|
|
|
|
pDeviceID Supplies a pointer to a NULL-terminated string specifying
|
|
the device instance ID for this new device instance. This
|
|
is the registry path (relative to the Enum branch) where
|
|
this device instance will be located (e.g., Root\*PNP0500\0000).
|
|
In Windows NT, this parameter is not optional.
|
|
|
|
dnParent Supplies the handle of the device instance that is the parent
|
|
of the device instance being created.
|
|
|
|
ulFlags Supplies flags specifying options for the creation of the
|
|
device instance. May be one of the following values:
|
|
|
|
CM_CREATE_DEVNODE_NORMAL
|
|
Create the device instance now, and perform installation
|
|
for it at a later time.
|
|
CM_CREATE_DEVNODE_NO_WAIT_INSTALL
|
|
Create the device instance, and perform installation for
|
|
it immediately.
|
|
CM_CREATE_DEVNODE_PHANTOM
|
|
Create a phantom device instance (i.e., a handle to a
|
|
device instance that is not alive as far as the ConfigMgr
|
|
APIs are concerned). This may be used for CM APIs that
|
|
require a devnode handle, but for which no real devnode
|
|
currently exists (e.g., registry property APIs). This
|
|
flag may not be specified with CR_CREATE_DEVNODE_NORMAL
|
|
or CR_CREATE_DEVNODE_NO_WAIT_INSTALL. A phantom devnode
|
|
created in this manner is not accessible to other callers
|
|
(i.e., CM_Locate_DevNode won't find it). However, callers
|
|
attempting to create a devnode with the same name as this
|
|
phantom devnode will not be able to do so (they will get
|
|
CR_ALREADY_SUCH_DEVNODE).
|
|
CM_CREATE_DEVNODE_GENERATE_ID
|
|
Create a Root-enumerated devnode using a unique device
|
|
instance ID generated from the supplied device ID in
|
|
pDeviceID. If this flag is set, then pDeviceID is assumed
|
|
to contain simply a device ID (i.e., no enumerator key
|
|
prefix, and no device instance suffix). A unique 4-digit,
|
|
base-10 identifier string will be created under
|
|
Enum\Root\<pDeviceID>, and the devnode will be created
|
|
based on that device instance ID. For instance, to add a
|
|
new legacy COM port devnode, this API would be called with
|
|
a pDeviceID of *PNP0500. Assuming there was already one
|
|
COM port instance in the registry (instance 0000), the new
|
|
device instance ID would be: Root\*PNP0500\0001
|
|
The caller may find out what device instance name was
|
|
generated by calling CM_Get_Device_ID with the devnode
|
|
returned from this API.
|
|
|
|
Return Value:
|
|
|
|
If the function succeeds, the return value is CR_SUCCESS.
|
|
If the function fails, the return value is one of the following:
|
|
CR_ALREADY_SUCH_DEVNODE,
|
|
CR_INVALID_DEVICE_ID,
|
|
CR_INVALID_DEVNODE,
|
|
CR_INVALID_FLAG,
|
|
CR_INVALID_POINTER, or
|
|
CR_OUT_OF_MEMORY.
|
|
|
|
--*/
|
|
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
LPWSTR pParentID = NULL;
|
|
WCHAR szNewDeviceID[MAX_DEVICE_ID_LEN];
|
|
PVOID hStringTable = NULL;
|
|
handle_t hBinding = NULL;
|
|
|
|
|
|
try {
|
|
//
|
|
// validate permission
|
|
//
|
|
if (!IsUserAdmin()) {
|
|
Status = CR_ACCESS_DENIED;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
if (pdnDevInst == NULL) {
|
|
Status = CR_INVALID_POINTER;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (dnParent == 0) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (pDeviceID == NULL || lstrlen(pDeviceID) > MAX_DEVICE_ID_LEN) {
|
|
Status = CR_INVALID_DEVICE_ID;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (INVALID_FLAGS(ulFlags, CM_CREATE_DEVNODE_BITS)) {
|
|
Status = CR_INVALID_FLAG;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// setup rpc binding handle and string table handle
|
|
//
|
|
if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
|
|
Status = CR_FAILURE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// retreive device instance string that corresponds to dnParent
|
|
// (note that this is not optional, even a first level device instance
|
|
// has a parent (the root device instance)
|
|
//
|
|
pParentID = StringTableStringFromId(hStringTable, dnParent);
|
|
if (pParentID == NULL || INVALID_DEVINST(pParentID)) {
|
|
Status = CR_INVALID_DEVNODE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// make sure the new device instance is properly formatted
|
|
//
|
|
CopyFixedUpDeviceId(szNewDeviceID, pDeviceID, lstrlen(pDeviceID));
|
|
|
|
|
|
|
|
RpcTryExcept {
|
|
//
|
|
// call rpc service entry point
|
|
//
|
|
Status = PNP_CreateDevInst(
|
|
hBinding, // rpc binding handle
|
|
szNewDeviceID, // device instance to create
|
|
pParentID, // parent device instance
|
|
MAX_DEVICE_ID_LEN, // max length of szNewDeviceID
|
|
ulFlags); // flags
|
|
}
|
|
RpcExcept (1) {
|
|
PnPTrace(
|
|
TEXT("PNP_CreateDevInst caused an exception (%d)\n"),
|
|
RpcExceptionCode());
|
|
Status = MapRpcExceptionToCR(RpcExceptionCode());
|
|
}
|
|
RpcEndExcept
|
|
|
|
if (Status != CR_SUCCESS) {
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// assign a unique device instance value to the newly created device
|
|
// instance
|
|
//
|
|
*pdnDevInst = StringTableAddString(hStringTable, szNewDeviceID,
|
|
STRTAB_CASE_SENSITIVE);
|
|
|
|
if (*pdnDevInst == 0) {
|
|
Status = CR_NO_SUCH_DEVNODE;
|
|
}
|
|
|
|
|
|
Clean0:
|
|
;
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
Status = CR_FAILURE;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Create_DevNodeW
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Move_DevNode_Ex(
|
|
IN DEVINST dnFromDevInst,
|
|
IN DEVINST dnToDevInst,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine replaces a root-enumerated device instance by the valid
|
|
non-root-enumerated device instance. The device installer uses this
|
|
service when it detects that a non-root enumerated device instance is
|
|
really the same as its root enumerated counterpart. This API migrates
|
|
the old device instance to the new location, and marks the old location
|
|
as having a problem. [TBD: what is this marking?]
|
|
|
|
Parameters:
|
|
|
|
dnFromDevNode Supplies the handle of the device instance that has been
|
|
root enumerated.
|
|
|
|
dnToDevNode Supplies the handle of the device instance that is a
|
|
reenumeration (duplicate) of the root device instance.
|
|
|
|
ulFlags Must be zero.
|
|
|
|
Return Value:
|
|
|
|
If the function succeeds, the return value is CR_SUCCESS.
|
|
If the function fails, the return value is one of the following:
|
|
CR_INVALID_FLAG,
|
|
CR_INVALID_DEVNODE,
|
|
CR_OUT_OF_MEMORY.
|
|
(Windows 95 may also return CR_NOT_AT_APPY_TIME.)
|
|
|
|
--*/
|
|
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
LPWSTR pFromDeviceID = NULL, pToDeviceID = NULL;
|
|
PVOID hStringTable = NULL;
|
|
handle_t hBinding = NULL;
|
|
|
|
|
|
try {
|
|
//
|
|
// validate permission
|
|
//
|
|
if (!IsUserAdmin()) {
|
|
Status = CR_ACCESS_DENIED;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
if (INVALID_FLAGS(ulFlags, 0)) {
|
|
Status = CR_INVALID_FLAG;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (dnFromDevInst == 0 || dnToDevInst == 0) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// setup rpc binding handle and string table handle
|
|
//
|
|
if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
|
|
Status = CR_FAILURE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// retrieve the device instance ID strings associated with both device
|
|
// instances passed in, both must be valid
|
|
//
|
|
pFromDeviceID = StringTableStringFromId(hStringTable, dnFromDevInst);
|
|
if (pFromDeviceID == NULL || INVALID_DEVINST(pFromDeviceID)) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
pToDeviceID = StringTableStringFromId(hStringTable, dnToDevInst);
|
|
if (pToDeviceID == NULL || INVALID_DEVINST(pToDeviceID)) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
|
|
RpcTryExcept {
|
|
//
|
|
// call rpc service entry point
|
|
//
|
|
Status = PNP_DeviceInstanceAction(
|
|
hBinding, // rpc binding handle
|
|
PNP_DEVINST_MOVE, // requested major action - MOVE
|
|
ulFlags, // requested minor action (not used)
|
|
pToDeviceID, // destination device instance
|
|
pFromDeviceID); // source device instance
|
|
}
|
|
RpcExcept (1) {
|
|
PnPTrace(TEXT(
|
|
"PNP_DeviceInstanceAction caused an exception (%d)\n"),
|
|
RpcExceptionCode());
|
|
Status = MapRpcExceptionToCR(RpcExceptionCode());
|
|
}
|
|
RpcEndExcept
|
|
|
|
|
|
Clean0:
|
|
;
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
Status = CR_FAILURE;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Move_DevNode_Ex
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Setup_DevNode_Ex(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine reenables and configures a specified device instance or
|
|
retrieves information from its enumerator.
|
|
|
|
Parameters:
|
|
|
|
dnDevNode Supplies the handle of the device instance which may be
|
|
reconfigured.
|
|
|
|
ulFlags Supplies a flag indicating the action to take. Can be one
|
|
of the following values:
|
|
|
|
CM_SETUP_DEVNODE_READY
|
|
Reenable the device instance that had a problem.
|
|
|
|
CM_SETUP_DOWNLOAD
|
|
Retrieve information about this device instance
|
|
from its enumerator.
|
|
|
|
Return Value:
|
|
|
|
If the function succeeds, the return value is CR_SUCCESS.
|
|
If the function fails, the return value is one of the following:
|
|
CR_INVALID_FLAG,
|
|
CR_INVALID_DEVNODE,
|
|
CR_OUT_OF_MEMORY, or
|
|
CR_FAILURE.
|
|
|
|
--*/
|
|
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
LPWSTR pDeviceID = NULL;
|
|
PVOID hStringTable = NULL;
|
|
handle_t hBinding = NULL;
|
|
|
|
|
|
try {
|
|
//
|
|
// validate permission
|
|
//
|
|
if (!IsUserAdmin()) {
|
|
Status = CR_ACCESS_DENIED;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
if (INVALID_FLAGS(ulFlags, CM_SETUP_DEVNODE_READY | CM_SETUP_DOWNLOAD)) {
|
|
Status = CR_INVALID_FLAG;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (dnDevInst == 0) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// setup rpc binding handle and string table handle
|
|
//
|
|
if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
|
|
Status = CR_FAILURE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// retrieve the device instance ID string associated with the devinst
|
|
//
|
|
pDeviceID = StringTableStringFromId(hStringTable, dnDevInst);
|
|
if (pDeviceID == NULL || INVALID_DEVINST(pDeviceID)) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
|
|
RpcTryExcept {
|
|
//
|
|
// call rpc service entry point
|
|
//
|
|
Status = PNP_DeviceInstanceAction(
|
|
hBinding, // rpc binding handle
|
|
PNP_DEVINST_SETUP, // requested major action - SETUP
|
|
ulFlags, // requested minor action
|
|
pDeviceID, // device instance to create
|
|
NULL); // (not used)
|
|
}
|
|
RpcExcept (1) {
|
|
PnPTrace(
|
|
TEXT("PNP_DeviceInstanceAction caused an exception (%d)\n"),
|
|
RpcExceptionCode());
|
|
Status = MapRpcExceptionToCR(RpcExceptionCode());
|
|
}
|
|
RpcEndExcept
|
|
|
|
|
|
Clean0:
|
|
;
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
Status = CR_FAILURE;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Setup_DevNode_Ex
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Disable_DevNode_Ex(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine disables a device instance.
|
|
|
|
Parameters:
|
|
|
|
dnDevNode Supplies the handle of the device instance to be disabled.
|
|
|
|
ulFlags Must be zero.
|
|
|
|
Return Value:
|
|
|
|
If the function succeeds, the return value is CR_SUCCESS.
|
|
If the function fails, the return value is one of the following:
|
|
CR_INVALID_FLAG,
|
|
CR_NOT_DISABLEABLE, or
|
|
CR_INVALID_DEVNODE.
|
|
(Note, Windows 95 also may return CR_NOT_AT_APPY_TIME.)
|
|
|
|
--*/
|
|
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
LPWSTR pDeviceID = NULL;
|
|
PVOID hStringTable = NULL;
|
|
handle_t hBinding = NULL;
|
|
|
|
|
|
try {
|
|
//
|
|
// validate permission
|
|
//
|
|
if (!IsUserAdmin()) {
|
|
Status = CR_ACCESS_DENIED;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
if (INVALID_FLAGS(ulFlags, CM_DISABLE_BITS)) {
|
|
Status = CR_INVALID_FLAG;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (dnDevInst == 0) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// setup rpc binding handle and string table handle
|
|
//
|
|
if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
|
|
Status = CR_FAILURE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// retrieve the device instance ID string associated with the devinst
|
|
//
|
|
pDeviceID = StringTableStringFromId(hStringTable, dnDevInst);
|
|
if (pDeviceID == NULL || INVALID_DEVINST(pDeviceID)) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
|
|
RpcTryExcept {
|
|
//
|
|
// call rpc service entry point
|
|
//
|
|
Status = PNP_DeviceInstanceAction(
|
|
hBinding, // rpc binding handle
|
|
PNP_DEVINST_DISABLE, // requested major action - DISABLE
|
|
ulFlags, // requested minor action (not used)
|
|
pDeviceID, // device instance to create
|
|
NULL); // (not used)
|
|
}
|
|
RpcExcept (1) {
|
|
PnPTrace(
|
|
TEXT("PNP_DeviceInstanceAction caused an exception (%d)\n"),
|
|
RpcExceptionCode());
|
|
Status = MapRpcExceptionToCR(RpcExceptionCode());
|
|
}
|
|
RpcEndExcept
|
|
|
|
|
|
Clean0:
|
|
;
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
Status = CR_FAILURE;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Disable_DevNode_Ex
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Enable_DevNode_Ex(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine enables a device instance.
|
|
|
|
Parameters:
|
|
|
|
dnDevNode Supplies the handle of the device instance to enable.
|
|
|
|
ulFlags Must be zero.
|
|
|
|
Return Value:
|
|
|
|
If the function succeeds, the return value is CR_SUCCESS.
|
|
If the function fails, the return value is one of the following:
|
|
CR_INVALID_FLAG or
|
|
CR_INVALID_DEVNODE.
|
|
(Note, Windows 95 also may return CR_NOT_AT_APPY_TIME.)
|
|
|
|
--*/
|
|
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
LPWSTR pDeviceID = NULL;
|
|
PVOID hStringTable = NULL;
|
|
handle_t hBinding = NULL;
|
|
|
|
|
|
try {
|
|
//
|
|
// validate permission
|
|
//
|
|
if (!IsUserAdmin()) {
|
|
Status = CR_ACCESS_DENIED;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
if (INVALID_FLAGS(ulFlags, 0)) {
|
|
Status = CR_INVALID_FLAG;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (dnDevInst == 0) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// setup rpc binding handle and string table handle
|
|
//
|
|
if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
|
|
Status = CR_FAILURE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// retrieve the device instance ID string associated with the devinst
|
|
//
|
|
pDeviceID = StringTableStringFromId(hStringTable, dnDevInst);
|
|
if (pDeviceID == NULL || INVALID_DEVINST(pDeviceID)) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
|
|
RpcTryExcept {
|
|
//
|
|
// call rpc service entry point
|
|
//
|
|
Status = PNP_DeviceInstanceAction(
|
|
hBinding, // rpc binding handle
|
|
PNP_DEVINST_ENABLE, // requested major action - ENABLE
|
|
ulFlags, // requested minor action (not used)
|
|
pDeviceID, // device instance to create
|
|
NULL); // (not used)
|
|
}
|
|
RpcExcept (1) {
|
|
PnPTrace(
|
|
TEXT("PNP_DeviceInstanceAction caused an exception (%d)\n"),
|
|
RpcExceptionCode());
|
|
Status = MapRpcExceptionToCR(RpcExceptionCode());
|
|
}
|
|
RpcEndExcept
|
|
|
|
|
|
Clean0:
|
|
;
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
Status = CR_FAILURE;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Enable_DevNode_Ex
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Get_DevNode_Status_Ex(
|
|
OUT PULONG pulStatus,
|
|
OUT PULONG pulProblemNumber,
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine retrieves the status of a device instance.
|
|
|
|
Parameters:
|
|
|
|
pulStatus Supplies the address of the variable that receives the
|
|
status flag of the device instance. Can be a combination
|
|
of the DN_* values.
|
|
|
|
pulProblemNumber Supplies the address of the variable that receives an
|
|
identifier indicating the problem. Can be one of the
|
|
CM_PROB_* values.
|
|
|
|
|
|
dnDevNode Supplies the handle of the device instance for which
|
|
to retrieve status.
|
|
|
|
ulFlags Must be zero.
|
|
|
|
Return Value:
|
|
|
|
If the function succeeds, the return value is CR_SUCCESS.
|
|
If the function fails, the return value is one of the following:
|
|
CR_INVALID_DEVNODE,
|
|
CR_INVALID_FLAG, or
|
|
CR_INVALID_POINTER.
|
|
|
|
--*/
|
|
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
LPWSTR pDeviceID = NULL;
|
|
PVOID hStringTable = NULL;
|
|
handle_t hBinding = NULL;
|
|
|
|
|
|
try {
|
|
//
|
|
// validate parameters
|
|
//
|
|
if (dnDevInst == 0) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (pulStatus == NULL || pulProblemNumber == NULL) {
|
|
Status = CR_INVALID_POINTER;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (INVALID_FLAGS(ulFlags, 0)) {
|
|
Status = CR_INVALID_FLAG;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// setup rpc binding handle and string table handle
|
|
//
|
|
if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
|
|
Status = CR_FAILURE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// retrieve the device instance ID string associated with the devinst
|
|
//
|
|
pDeviceID = StringTableStringFromId(hStringTable, dnDevInst);
|
|
if (pDeviceID == NULL) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
|
|
RpcTryExcept {
|
|
//
|
|
// call rpc service entry point
|
|
//
|
|
Status = PNP_GetDeviceStatus(
|
|
hBinding, // rpc binding handle
|
|
pDeviceID, // device instance to get status for
|
|
pulStatus, // return StatusFlags here
|
|
pulProblemNumber, // return Problem here
|
|
ulFlags); // (not used)
|
|
}
|
|
RpcExcept (1) {
|
|
PnPTrace(
|
|
TEXT("PNP_GetDeviceAction caused an exception (%d)\n"),
|
|
RpcExceptionCode());
|
|
Status = MapRpcExceptionToCR(RpcExceptionCode());
|
|
}
|
|
RpcEndExcept
|
|
|
|
|
|
Clean0:
|
|
;
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
Status = CR_FAILURE;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Get_DevNode_Status_Ex
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Reenumerate_DevNode_Ex(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine causes the specified device instance to be enumerated
|
|
(if it is enumerable).
|
|
|
|
Parameters:
|
|
|
|
dnDevNode Supplies the handle of the device instance to be enumerated.
|
|
|
|
ulFlags Must be zero.
|
|
|
|
Return Value:
|
|
|
|
If the function succeeds, the return value is CR_SUCCESS.
|
|
If the function fails, the return value is CR_INVALID_FLAG (i.e., the
|
|
function does not fail). The device instance is not checked for validity.
|
|
|
|
--*/
|
|
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
LPWSTR pDeviceID = NULL;
|
|
PVOID hStringTable = NULL;
|
|
handle_t hBinding = NULL;
|
|
|
|
|
|
try {
|
|
//
|
|
// validate permission
|
|
//
|
|
if (!IsUserAdmin()) {
|
|
Status = CR_ACCESS_DENIED;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
if (INVALID_FLAGS(ulFlags, CM_REENUMERATE_BITS)) {
|
|
Status = CR_INVALID_FLAG;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (dnDevInst == 0) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// setup rpc binding handle and string table handle
|
|
//
|
|
if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
|
|
Status = CR_FAILURE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// retrieve the device instance ID string associated with the devinst
|
|
//
|
|
pDeviceID = StringTableStringFromId(hStringTable, dnDevInst);
|
|
if (pDeviceID == NULL || INVALID_DEVINST(pDeviceID)) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
|
|
RpcTryExcept {
|
|
//
|
|
// call rpc service entry point
|
|
//
|
|
Status = PNP_DeviceInstanceAction(
|
|
hBinding, // rpc binding handle
|
|
PNP_DEVINST_REENUMERATE, // requested major action-REMOVESUBTREE
|
|
ulFlags, // requested minor action
|
|
pDeviceID, // device instance subtree to remove
|
|
NULL); // (not used)
|
|
}
|
|
RpcExcept (1) {
|
|
PnPTrace(
|
|
TEXT("PNP_DeviceInstanceAction caused an exception (%d)\n"),
|
|
RpcExceptionCode());
|
|
Status = MapRpcExceptionToCR(RpcExceptionCode());
|
|
}
|
|
RpcEndExcept
|
|
|
|
|
|
Clean0:
|
|
;
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
Status = CR_FAILURE;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Reenumerate_DevNode_Ex
|
|
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Query_Remove_SubTree_Ex(
|
|
IN DEVINST dnAncestor,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine checks whether a device instance and its progeny can be
|
|
removed. This API must be called before calling CM_Remove_SubTree to
|
|
make sure applications prepare for the removal of the device or to
|
|
give the applications a chance to deny the request to remove the device.
|
|
If the removal happens “surprise style” (i.e., there’s no advanced
|
|
warning or chance to veto), then this API should not be called before
|
|
calling CM_Remove_SubTree.
|
|
|
|
Parameters:
|
|
|
|
dnAncestor Supplies the handle of the device instance at the root of
|
|
the subtree to be removed.
|
|
|
|
ulFlags Specifies whether UI should be presented for
|
|
this action. Can be one of the following values:
|
|
|
|
CM_QUERY_REMOVE_UI_OK - OK to present UI for query-removal.
|
|
CM_QUERY_REMOVE_UI_NOT_OK -Don't present UI for query-removal.
|
|
|
|
Return Value:
|
|
|
|
If the function succeeds, the return value is CR_SUCCESS.
|
|
If the function fails, the return value is one of the following:
|
|
CR_INVALID_DEVNODE,
|
|
CR_INVALID_FLAG,
|
|
CR_REMOVE_VETOED. (Windows 95 may also return CR_NOT_AT_APPY_TIME.)
|
|
|
|
--*/
|
|
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
LPWSTR pDeviceID = NULL;
|
|
PVOID hStringTable = NULL;
|
|
handle_t hBinding = NULL;
|
|
|
|
|
|
try {
|
|
//
|
|
// validate permission
|
|
//
|
|
if (!IsUserAdmin()) {
|
|
Status = CR_ACCESS_DENIED;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
if (dnAncestor == 0) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (INVALID_FLAGS(ulFlags, CM_QUERY_REMOVE_BITS)) {
|
|
Status = CR_INVALID_FLAG;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// setup rpc binding handle and string table handle
|
|
//
|
|
if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
|
|
Status = CR_FAILURE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// retrieve the device instance ID string associated with the devinst
|
|
//
|
|
pDeviceID = StringTableStringFromId(hStringTable, dnAncestor);
|
|
if (pDeviceID == NULL || INVALID_DEVINST(pDeviceID)) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
|
|
RpcTryExcept {
|
|
//
|
|
// call rpc service entry point
|
|
//
|
|
Status = PNP_DeviceInstanceAction(
|
|
hBinding, // rpc binding handle
|
|
PNP_DEVINST_QUERYREMOVE, // requested major action-QUERYREMOVE
|
|
ulFlags, // requested minor action (not used)
|
|
pDeviceID, // device instance subtree to remove
|
|
NULL); // (not used)
|
|
}
|
|
RpcExcept (1) {
|
|
PnPTrace(
|
|
TEXT("PNP_DeviceInstanceAction caused an exception (%d)\n"),
|
|
RpcExceptionCode());
|
|
Status = MapRpcExceptionToCR(RpcExceptionCode());
|
|
}
|
|
RpcEndExcept
|
|
|
|
|
|
Clean0:
|
|
;
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
Status = CR_FAILURE;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Query_Remove_SubTree_Ex
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Remove_SubTree_Ex(
|
|
IN DEVINST dnAncestor,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine removes a device instance and its children from the
|
|
running system. This API notifies each device instance in the subtree
|
|
of the dnAncestor parameter of the device's removal. (On Windows NT,
|
|
this means that each driver/service controlling a device in this
|
|
subtree receives a device removal notification.)
|
|
|
|
Parameters:
|
|
|
|
dnAncestor Supplies the handle of the device instance that is being removed.
|
|
|
|
ulFlags Must be either CM_REMOVE_UI_OK or CM_REMOVE_UI_NOT_OK.
|
|
|
|
Return Value:
|
|
|
|
If the function succeeds, the return value is CR_SUCCESS.
|
|
If the function fails, the return value is one of the following:
|
|
CR_INVALID_DEVNODE or
|
|
CR_INVALID_FLAG.
|
|
(Windows 95 may also return CR_NOT_AT_APPY_TIME.)
|
|
|
|
--*/
|
|
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
LPWSTR pDeviceID = NULL;
|
|
PVOID hStringTable = NULL;
|
|
handle_t hBinding = NULL;
|
|
|
|
|
|
try {
|
|
//
|
|
// validate permission
|
|
//
|
|
if (!IsUserAdmin()) {
|
|
Status = CR_ACCESS_DENIED;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
if (dnAncestor == 0) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (INVALID_FLAGS(ulFlags, CM_REMOVE_BITS)) {
|
|
Status = CR_INVALID_FLAG;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// setup rpc binding handle and string table handle
|
|
//
|
|
if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
|
|
Status = CR_FAILURE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// retrieve the device instance ID string associated with the devinst
|
|
//
|
|
pDeviceID = StringTableStringFromId(hStringTable, dnAncestor);
|
|
if (pDeviceID == NULL || INVALID_DEVINST(pDeviceID)) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
|
|
RpcTryExcept {
|
|
//
|
|
// call rpc service entry point
|
|
//
|
|
Status = PNP_DeviceInstanceAction(
|
|
hBinding, // rpc binding handle
|
|
PNP_DEVINST_REMOVESUBTREE, // requested major action-REMOVESUBTREE
|
|
ulFlags, // requested minor action (not used)
|
|
pDeviceID, // device instance subtree to remove
|
|
NULL); // (not used)
|
|
}
|
|
RpcExcept (1) {
|
|
PnPTrace(
|
|
TEXT("PNP_DeviceInstanceAction caused an exception (%d)\n"),
|
|
RpcExceptionCode());
|
|
Status = MapRpcExceptionToCR(RpcExceptionCode());
|
|
}
|
|
RpcEndExcept
|
|
|
|
|
|
Clean0:
|
|
;
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
Status = CR_FAILURE;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Remove_SubTree
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Uninstall_DevNode_Ex(
|
|
IN DEVNODE dnDevInst,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine uninstalls a device instance (i.e., deletes its registry
|
|
key(s) in the Enum branch). This API can only be called for phantom
|
|
device instances, and the handle supplied is invalid after the call.
|
|
This API does not attempt to delete all possible storage locations
|
|
associated with the device instance. It will do a recursive delete on
|
|
the devnode key, so that any subkeys will be removed. It will also
|
|
delete the devnode key (and any subkeys) located in the Enum branch
|
|
of each hardware profile. It will not delete any software keys or user
|
|
keys (CM_Delete_DevNode_Key must be called to do that before calling
|
|
this API).
|
|
|
|
Parameters:
|
|
|
|
dnPhantom Handle of a phantom device instance to uninstall. This
|
|
handle is typically retrieved by a call to CM_Locate_DevNode
|
|
or CM_Create_DevNode.
|
|
|
|
ulFlags Must be zero.
|
|
|
|
Return Value:
|
|
|
|
If the function succeeds, the return value is CR_SUCCESS.
|
|
If the function fails, the return value is one of the following:
|
|
CR_INVALID_DEVNODE,
|
|
CR_INVALID_FLAG, or
|
|
CR_REGISTRY_ERROR
|
|
|
|
--*/
|
|
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
LPWSTR pDeviceID = NULL;
|
|
PVOID hStringTable = NULL;
|
|
handle_t hBinding = NULL;
|
|
WCHAR szParentKey[MAX_DEVICE_ID_LEN],
|
|
szChildKey[MAX_DEVICE_ID_LEN];
|
|
|
|
|
|
try {
|
|
//
|
|
// validate parameters
|
|
//
|
|
if (dnDevInst == 0) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (INVALID_FLAGS(ulFlags, 0)) {
|
|
Status = CR_INVALID_FLAG;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// setup rpc binding handle and string table handle
|
|
//
|
|
if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
|
|
Status = CR_FAILURE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// retrieve the device instance ID string associated with the devinst
|
|
//
|
|
pDeviceID = StringTableStringFromId(hStringTable, dnDevInst);
|
|
if (pDeviceID == NULL || INVALID_DEVINST(pDeviceID)) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
|
|
RpcTryExcept {
|
|
//
|
|
// call rpc service entry point
|
|
//
|
|
Status = PNP_UninstallDevInst(
|
|
hBinding, // rpc binding handle
|
|
pDeviceID, // device instance to uninstall
|
|
ulFlags); // (unused)
|
|
}
|
|
RpcExcept (1) {
|
|
PnPTrace(
|
|
TEXT("PNP_DeinstallDevInst caused an exception (%d)\n"),
|
|
RpcExceptionCode());
|
|
Status = MapRpcExceptionToCR(RpcExceptionCode());
|
|
}
|
|
RpcEndExcept
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
// after deleting the main hw key and the config specific hw keys,
|
|
// cleanup the user hw key, which can only be done on the client
|
|
// side.
|
|
//------------------------------------------------------------------
|
|
|
|
//
|
|
// form the user hardware registry key path
|
|
//
|
|
Status = GetDevNodeKeyPath(hBinding, pDeviceID,
|
|
CM_REGISTRY_HARDWARE | CM_REGISTRY_USER,
|
|
0, szParentKey, szChildKey);
|
|
|
|
if (Status != CR_SUCCESS) {
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// delete the specified private user key
|
|
//
|
|
Status = DeletePrivateKey(HKEY_CURRENT_USER, szParentKey, szChildKey);
|
|
|
|
|
|
Clean0:
|
|
;
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
Status = CR_FAILURE;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Uninstall_DevNode
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Add_ID_ExW(
|
|
IN DEVINST dnDevInst,
|
|
IN PWSTR pszID,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine adds a device ID to a device instance’s HardwareID or
|
|
CompatibleIDs list.
|
|
|
|
Parameters:
|
|
|
|
dnDevInst Handle of a device instance. This handle is typically
|
|
retrieved by a call to CM_Locate_DevNode or CM_Create_DevNode.
|
|
|
|
pszID Supplies a pointer to a NULL-terminated string specifying
|
|
the ID to be added.
|
|
|
|
ulFlags Supplies flags for the ID. May be one of the following values:
|
|
|
|
ID Type Flags:
|
|
CM_ADD_ID_HARDWARE The specified ID is a hardware ID. Add
|
|
it to the device instance's HardwareID
|
|
list.
|
|
CM_ADD_ID_COMPATIBLE The specified ID is a compatible ID.
|
|
Add it to the device instance's
|
|
CompatibleIDs list.
|
|
|
|
Return Value:
|
|
|
|
If the function succeeds, the return value is CR_SUCCESS.
|
|
If the function fails, the return value is a CR error code.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
LPWSTR pDeviceID = NULL;
|
|
PVOID hStringTable = NULL;
|
|
handle_t hBinding = NULL;
|
|
|
|
|
|
try {
|
|
//
|
|
// validate permission
|
|
//
|
|
if (!IsUserAdmin()) {
|
|
Status = CR_ACCESS_DENIED;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
if (dnDevInst == 0) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (pszID == NULL) {
|
|
Status = CR_INVALID_POINTER;
|
|
goto Clean0;
|
|
}
|
|
|
|
if (INVALID_FLAGS(ulFlags, CM_ADD_ID_HARDWARE | CM_ADD_ID_COMPATIBLE)) {
|
|
Status = CR_INVALID_FLAG;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// setup rpc binding handle and string table handle
|
|
//
|
|
if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
|
|
Status = CR_FAILURE;
|
|
goto Clean0;
|
|
}
|
|
|
|
//
|
|
// retrieve the device instance ID string associated with the devinst
|
|
//
|
|
pDeviceID = StringTableStringFromId(hStringTable, dnDevInst);
|
|
if (pDeviceID == NULL || INVALID_DEVINST(pDeviceID)) {
|
|
Status = CR_INVALID_DEVINST;
|
|
goto Clean0;
|
|
}
|
|
|
|
|
|
RpcTryExcept {
|
|
//
|
|
// call rpc service entry point
|
|
//
|
|
Status = PNP_AddID(
|
|
hBinding, // rpc binding handle
|
|
pDeviceID, // device instance
|
|
pszID, // id to add
|
|
ulFlags); // hardware or compatible
|
|
}
|
|
RpcExcept (1) {
|
|
PnPTrace(
|
|
TEXT("PNP_AddID caused an exception (%d)\n"),
|
|
RpcExceptionCode());
|
|
Status = MapRpcExceptionToCR(RpcExceptionCode());
|
|
}
|
|
RpcEndExcept
|
|
|
|
|
|
Clean0:
|
|
;
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
Status = CR_FAILURE;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Add_ID_ExW
|
|
|
|
|
|
|
|
#if 0
|
|
//-------------------------------------------------------------------
|
|
// NOT IMPLEMENTED ROUTINES
|
|
//-------------------------------------------------------------------
|
|
|
|
|
|
CONFIGRET
|
|
CM_Remove_Unmarked_Children_Ex(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
{
|
|
return CR_CALL_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
CONFIGRET
|
|
CM_Reset_Children_Marks_Ex(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
{
|
|
return CR_CALL_NOT_IMPLEMENTED;
|
|
}
|
|
#endif
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
// Local Stubs
|
|
//-------------------------------------------------------------------
|
|
|
|
|
|
CONFIGRET
|
|
CM_Create_DevNodeW(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINSTID_W pDeviceID,
|
|
IN DEVINST dnParent,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Create_DevNode_ExW(pdnDevInst, pDeviceID, dnParent,
|
|
ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Create_DevNodeA(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINSTID_A pDeviceID,
|
|
IN DEVINST dnParent,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Create_DevNode_ExA(pdnDevInst, pDeviceID, dnParent,
|
|
ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Move_DevNode(
|
|
IN DEVINST dnFromDevInst,
|
|
IN DEVINST dnToDevInst,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Move_DevNode_Ex(dnFromDevInst, dnToDevInst, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Setup_DevNode(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Setup_DevNode_Ex(dnDevInst, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Disable_DevNode(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Disable_DevNode_Ex(dnDevInst, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Enable_DevNode(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Enable_DevNode_Ex(dnDevInst, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Get_DevNode_Status(
|
|
OUT PULONG pulStatus,
|
|
OUT PULONG pulProblemNumber,
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber,
|
|
dnDevInst, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Reenumerate_DevNode(
|
|
IN DEVINST dnDevInst,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Reenumerate_DevNode_Ex(dnDevInst, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Remove_SubTree(
|
|
IN DEVINST dnAncestor,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Remove_SubTree_Ex(dnAncestor, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Uninstall_DevNode(
|
|
IN DEVNODE dnPhantom,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Uninstall_DevNode_Ex(dnPhantom, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Add_IDW(
|
|
IN DEVINST dnDevInst,
|
|
IN PWSTR pszID,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Add_ID_ExW(dnDevInst, pszID, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Add_IDA(
|
|
IN DEVINST dnDevInst,
|
|
IN PSTR pszID,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Add_ID_ExA(dnDevInst, pszID, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
CONFIGRET
|
|
CM_Query_Remove_SubTree(
|
|
IN DEVINST dnAncestor,
|
|
IN ULONG ulFlags
|
|
)
|
|
{
|
|
return CM_Query_Remove_SubTree_Ex(dnAncestor, ulFlags, NULL);
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
// ANSI STUBS
|
|
//-------------------------------------------------------------------
|
|
|
|
|
|
CONFIGRET
|
|
CM_Add_ID_ExA(
|
|
IN DEVINST dnDevInst,
|
|
IN PSTR pszID,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
PWSTR pUniID = NULL;
|
|
|
|
|
|
if (CaptureAndConvertAnsiArg(pszID, &pUniID) == NO_ERROR) {
|
|
|
|
Status = CM_Add_ID_ExW(dnDevInst,
|
|
pUniID,
|
|
ulFlags,
|
|
hMachine);
|
|
MyFree(pUniID);
|
|
|
|
} else {
|
|
Status = CR_INVALID_POINTER;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Add_ID_ExA
|
|
|
|
|
|
|
|
|
|
CONFIGRET
|
|
CM_Create_DevNode_ExA(
|
|
OUT PDEVINST pdnDevInst,
|
|
IN DEVINSTID_A pDeviceID,
|
|
IN DEVINST dnParent,
|
|
IN ULONG ulFlags,
|
|
IN HMACHINE hMachine
|
|
)
|
|
{
|
|
CONFIGRET Status = CR_SUCCESS;
|
|
PWSTR pUniDeviceID = NULL;
|
|
|
|
|
|
if (CaptureAndConvertAnsiArg(pDeviceID, &pUniDeviceID) == NO_ERROR) {
|
|
|
|
Status = CM_Create_DevNode_ExW(pdnDevInst,
|
|
pUniDeviceID,
|
|
dnParent,
|
|
ulFlags,
|
|
hMachine);
|
|
MyFree(pUniDeviceID);
|
|
|
|
} else {
|
|
Status = CR_INVALID_DEVICE_ID;
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // CM_Create_DevNode_ExA
|
|
|
|
|