📄 devcon.cpp
字号:
/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
devcon.cpp
Abstract:
Device Console
command-line interface for managing devices
--*/
#include "devcon.h"
struct IdEntry {
LPCTSTR String; // string looking for
LPCTSTR Wild; // first wild character if any
BOOL InstanceId;
};
void FormatToStream(FILE * stream,DWORD fmt,...)
/*++
Routine Description:
Format text to stream using a particular msg-id fmt
Used for displaying localizable messages
Arguments:
stream - file stream to output to, stdout or stderr
fmt - message id
... - parameters %1...
Return Value:
none
--*/
{
va_list arglist;
LPTSTR locbuffer = NULL;
DWORD count;
va_start(arglist, fmt);
count = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL,
fmt,
0, // LANGID
(LPTSTR) &locbuffer,
0, // minimum size of buffer
&arglist);
if(locbuffer) {
if(count) {
int c;
int back = 0;
//
// strip any trailing "\r\n"s and replace by a single "\n"
//
while(((c = *CharPrev(locbuffer,locbuffer+count)) == TEXT('\r')) ||
(c == TEXT('\n'))) {
count--;
back++;
}
if(back) {
locbuffer[count++] = TEXT('\n');
locbuffer[count] = TEXT('\0');
}
//
// now write to apropriate stream
//
_fputts(locbuffer,stream);
}
LocalFree(locbuffer);
}
}
void Padding(int pad)
/*++
Routine Description:
Insert padding into line before text
Arguments:
pad - number of padding tabs to insert
Return Value:
none
--*/
{
int c;
for(c=0;c<pad;c++) {
fputs(" ",stdout);
}
}
void Usage(LPCTSTR BaseName)
/*++
Routine Description:
Display simple usage text
Arguments:
BaseName - name of executable
Return Value:
none
--*/
{
FormatToStream(stderr,MSG_USAGE,BaseName);
}
void CommandUsage(LPCTSTR BaseName,LPCTSTR Cmd)
/*++
Routine Description:
Invalid command usage
Display how to get help on command
Arguments:
BaseName - name of executable
Return Value:
none
--*/
{
FormatToStream(stderr,MSG_COMMAND_USAGE,BaseName,Cmd);
}
void Failure(LPCTSTR BaseName,LPCTSTR Cmd)
/*++
Routine Description:
Display simple error text for general failure
Arguments:
BaseName - name of executable
Return Value:
none
--*/
{
FormatToStream(stderr,MSG_FAILURE,BaseName,Cmd);
}
BOOL Reboot()
/*++
Routine Description:
Attempt to reboot computer
Arguments:
none
Return Value:
TRUE if API suceeded
--*/
{
HANDLE Token;
BOOL b;
TOKEN_PRIVILEGES NewPrivileges;
LUID Luid;
//
// we need to "turn on" reboot privilege
// if any of this fails, try reboot anyway
//
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&Token)) {
goto final;
}
if(!LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&Luid)) {
CloseHandle(Token);
goto final;
}
NewPrivileges.PrivilegeCount = 1;
NewPrivileges.Privileges[0].Luid = Luid;
NewPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(
Token,
FALSE,
&NewPrivileges,
0,
NULL,
NULL
);
CloseHandle(Token);
final:
//
// attempt reboot - inform system that this is planned hardware install
//
return ExitWindowsEx(EWX_REBOOT, REASON_PLANNED_FLAG|REASON_HWINSTALL);
}
LPTSTR GetDeviceStringProperty(HDEVINFO Devs,PSP_DEVINFO_DATA DevInfo,DWORD Prop)
/*++
Routine Description:
Return a string property for a device, otherwise NULL
Arguments:
Devs )_ uniquely identify device
DevInfo )
Prop - string property to obtain
Return Value:
string containing description
--*/
{
LPTSTR buffer;
DWORD size;
DWORD reqSize;
DWORD dataType;
DWORD szChars;
size = 1024; // initial guess
buffer = new TCHAR[(size/sizeof(TCHAR))+1];
if(!buffer) {
return NULL;
}
while(!SetupDiGetDeviceRegistryProperty(Devs,DevInfo,Prop,&dataType,(LPBYTE)buffer,size,&reqSize)) {
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
goto failed;
}
if(dataType != REG_SZ) {
goto failed;
}
size = reqSize;
delete [] buffer;
buffer = new TCHAR[(size/sizeof(TCHAR))+1];
if(!buffer) {
goto failed;
}
}
szChars = reqSize/sizeof(TCHAR);
buffer[szChars] = TEXT('\0');
return buffer;
failed:
if(buffer) {
delete [] buffer;
}
return NULL;
}
LPTSTR GetDeviceDescription(HDEVINFO Devs,PSP_DEVINFO_DATA DevInfo)
/*++
Routine Description:
Return a string containing a description of the device, otherwise NULL
Always try friendly name first
Arguments:
Devs )_ uniquely identify device
DevInfo )
Return Value:
string containing description
--*/
{
LPTSTR desc;
desc = GetDeviceStringProperty(Devs,DevInfo,SPDRP_FRIENDLYNAME);
if(!desc) {
desc = GetDeviceStringProperty(Devs,DevInfo,SPDRP_DEVICEDESC);
}
return desc;
}
IdEntry GetIdType(LPCTSTR Id)
/*++
Routine Description:
Determine if this is instance id or hardware id and if there's any wildcards
instance ID is prefixed by '@'
wildcards are '*'
Arguments:
Id - ptr to string to check
Return Value:
IdEntry
--*/
{
IdEntry Entry;
Entry.InstanceId = FALSE;
Entry.Wild = NULL;
Entry.String = Id;
if(Entry.String[0] == INSTANCEID_PREFIX_CHAR) {
Entry.InstanceId = TRUE;
Entry.String = CharNext(Entry.String);
}
if(Entry.String[0] == QUOTE_PREFIX_CHAR) {
//
// prefix to treat rest of string literally
//
Entry.String = CharNext(Entry.String);
} else {
//
// see if any wild characters exist
//
Entry.Wild = _tcschr(Entry.String,WILD_CHAR);
}
return Entry;
}
LPTSTR * GetMultiSzIndexArray(LPTSTR MultiSz)
/*++
Routine Description:
Get an index array pointing to the MultiSz passed in
Arguments:
MultiSz - well formed multi-sz string
Return Value:
array of strings. last entry+1 of array contains NULL
returns NULL on failure
--*/
{
LPTSTR scan;
LPTSTR * array;
int elements;
for(scan = MultiSz, elements = 0; scan[0] ;elements++) {
scan += lstrlen(scan)+1;
}
array = new LPTSTR[elements+2];
if(!array) {
return NULL;
}
array[0] = MultiSz;
array++;
if(elements) {
for(scan = MultiSz, elements = 0; scan[0]; elements++) {
array[elements] = scan;
scan += lstrlen(scan)+1;
}
}
array[elements] = NULL;
return array;
}
LPTSTR * CopyMultiSz(LPTSTR * Array)
/*++
Routine Description:
Creates a new array from old
old array need not have been allocated by GetMultiSzIndexArray
Arguments:
Array - array of strings, last entry is NULL
Return Value:
MultiSz array allocated by GetMultiSzIndexArray
--*/
{
LPTSTR multiSz = NULL;
int len = 0;
int c;
if(Array) {
for(c=0;Array[c];c++) {
len+=lstrlen(Array[c])+1;
}
}
len+=1; // final Null
multiSz = new TCHAR[len];
if(!multiSz) {
return NULL;
}
len = 0;
if(Array) {
for(c=0;Array[c];c++) {
lstrcpy(multiSz+len,Array[c]);
len+=lstrlen(multiSz+len)+1;
}
}
multiSz[len] = TEXT('\0');
LPTSTR * pRes = GetMultiSzIndexArray(multiSz);
if(pRes) {
return pRes;
}
delete [] multiSz;
return NULL;
}
void DelMultiSz(LPTSTR * Array)
/*++
Routine Description:
Deletes the string array allocated by GetDevMultiSz/GetRegMultiSz/GetMultiSzIndexArray
Arguments:
Array - pointer returned by GetMultiSzIndexArray
Return Value:
None
--*/
{
if(Array) {
Array--;
if(Array[0]) {
delete [] Array[0];
}
delete [] Array;
}
}
LPTSTR * GetDevMultiSz(HDEVINFO Devs,PSP_DEVINFO_DATA DevInfo,DWORD Prop)
/*++
Routine Description:
Get a multi-sz device property
and return as an array of strings
Arguments:
Devs - HDEVINFO containing DevInfo
DevInfo - Specific device
Prop - SPDRP_HARDWAREID or SPDRP_COMPATIBLEIDS
Return Value:
array of strings. last entry+1 of array contains NULL
returns NULL on failure
--*/
{
LPTSTR buffer;
DWORD size;
DWORD reqSize;
DWORD dataType;
LPTSTR * array;
DWORD szChars;
size = 8192; // initial guess, nothing magic about this
buffer = new TCHAR[(size/sizeof(TCHAR))+2];
if(!buffer) {
return NULL;
}
while(!SetupDiGetDeviceRegistryProperty(Devs,DevInfo,Prop,&dataType,(LPBYTE)buffer,size,&reqSize)) {
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
goto failed;
}
if(dataType != REG_MULTI_SZ) {
goto failed;
}
size = reqSize;
delete [] buffer;
buffer = new TCHAR[(size/sizeof(TCHAR))+2];
if(!buffer) {
goto failed;
}
}
szChars = reqSize/sizeof(TCHAR);
buffer[szChars] = TEXT('\0');
buffer[szChars+1] = TEXT('\0');
array = GetMultiSzIndexArray(buffer);
if(array) {
return array;
}
failed:
if(buffer) {
delete [] buffer;
}
return NULL;
}
LPTSTR * GetRegMultiSz(HKEY hKey,LPCTSTR Val)
/*++
Routine Description:
Get a multi-sz from registry
and return as an array of strings
Arguments:
hKey - Registry Key
Val - Value to query
Return Value:
array of strings. last entry+1 of array contains NULL
returns NULL on failure
--*/
{
LPTSTR buffer;
DWORD size;
DWORD reqSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -