535 lines
16 KiB
C++
535 lines
16 KiB
C++
//***************************************************************************
|
|
//
|
|
// getparams.cpp
|
|
//
|
|
// Module: WMI Instance provider code for boot parameters
|
|
//
|
|
// Purpose: Extracting boot parameters.
|
|
//
|
|
// Copyright (c) 1997-1999 Microsoft Corporation
|
|
//
|
|
//***************************************************************************
|
|
|
|
#include "bootini.h"
|
|
|
|
SCODE ParseLine(IWbemClassObject *pNewOSInst,
|
|
PCHAR line,
|
|
PCHAR options
|
|
)
|
|
{
|
|
PCHAR rest; // the rest of the options cannot be bigger than this.
|
|
int size = strlen(line);
|
|
int len;
|
|
SCODE sc;
|
|
VARIANT v;
|
|
BOOL found=FALSE;
|
|
|
|
rest = (PCHAR) BPAlloc(size);
|
|
if (!rest) {
|
|
return WBEM_E_FAILED;
|
|
}
|
|
PWCHAR wstr;
|
|
wstr = (PWCHAR) BPAlloc(size*sizeof(WCHAR));
|
|
if (!wstr) {
|
|
BPFree(rest);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
|
|
*options = 0; //Later fill in the '='
|
|
len = MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
line,
|
|
strlen(line),
|
|
wstr,
|
|
size
|
|
);
|
|
wstr[len] = (WCHAR) 0;
|
|
v.vt = VT_BSTR;
|
|
v.bstrVal = SysAllocString(wstr);
|
|
sc = pNewOSInst->Put(L"Directory", 0,&v, 0);
|
|
VariantClear(&v);
|
|
PCHAR temp = options + 1;
|
|
*options = '=';
|
|
PCHAR temp1;
|
|
// Rest of the stuff is filled in during initialization
|
|
while(*temp){ // We know line ends with a null
|
|
while(*temp && *temp == ' '){
|
|
temp ++;
|
|
}
|
|
if(*temp == 0) break;
|
|
// Get the new string
|
|
temp1 = temp;
|
|
if(*temp == '"'){
|
|
// could be the name of the OS
|
|
do {
|
|
temp1++;
|
|
}while(*temp1 && (*temp1 != '"'));
|
|
if(*temp1){
|
|
temp1++;
|
|
}
|
|
else{
|
|
BPFree(rest);
|
|
BPFree(wstr);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
len = MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
temp,
|
|
temp1-temp,
|
|
wstr,
|
|
size
|
|
);
|
|
wstr[len] = (WCHAR) 0;
|
|
v.vt = VT_BSTR;
|
|
v.bstrVal = SysAllocString(wstr);
|
|
sc = pNewOSInst->Put(L"OperatingSystem", 0,&v, 0);
|
|
VariantClear(&v);
|
|
temp = temp1;
|
|
continue;
|
|
}
|
|
do{
|
|
temp1++;
|
|
}while((*temp1) && (*temp1 != ' ') && (*temp1 != '/'));
|
|
// Now we have the option between temp1 and temp2.
|
|
if(strncmp(temp,"/redirect", strlen("/redirect")) == 0){
|
|
v.vt = VT_BOOL;
|
|
v.boolVal = TRUE;
|
|
sc = pNewOSInst->Put(L"Redirect", 0,&v, 0);
|
|
VariantClear(&v);
|
|
temp = temp1;
|
|
continue;
|
|
}
|
|
if(strncmp(temp,"/debug", strlen("/debug")) == 0){
|
|
// fill in the redirect flag.
|
|
v.vt = VT_BOOL;
|
|
v.boolVal = TRUE;
|
|
sc = pNewOSInst->Put(L"Debug", 0,&v, 0);
|
|
VariantClear(&v);
|
|
temp = temp1;
|
|
continue;
|
|
}
|
|
|
|
if(strncmp(temp,"/fastdetect", strlen("/fastdetect")) == 0){
|
|
// fill in the redirect flag.
|
|
v.vt = VT_BOOL;
|
|
v.boolVal = TRUE;
|
|
sc = pNewOSInst->Put(L"Fastdetect", 0,&v, 0);
|
|
VariantClear(&v);
|
|
temp = temp1;
|
|
continue;
|
|
}
|
|
strncat(rest,temp, temp1-temp);
|
|
strcat(rest," ");
|
|
temp = temp1;
|
|
}
|
|
len = MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
rest,
|
|
strlen(rest),
|
|
wstr,
|
|
size
|
|
);
|
|
wstr[len] = (WCHAR) 0;
|
|
v.vt=VT_BSTR;
|
|
v.bstrVal = SysAllocString(wstr);
|
|
sc = pNewOSInst->Put(L"Rest", 0,&v, 0);
|
|
VariantClear(&v);
|
|
BPFree(rest);
|
|
BPFree(wstr);
|
|
return sc;
|
|
}
|
|
|
|
|
|
SCODE
|
|
ParseBootFile(IWbemClassObject *pClass,
|
|
PCHAR data,
|
|
PWCHAR *wdef,
|
|
PCHAR red,
|
|
PLONG pdelay,
|
|
SAFEARRAY **psa
|
|
)
|
|
{
|
|
IWbemClassObject FAR* pNewOSInst;
|
|
HRESULT ret;
|
|
int dwRet;
|
|
SCODE sc;
|
|
SAFEARRAYBOUND bound[1];
|
|
long index;
|
|
PCHAR def=NULL;
|
|
PCHAR pChar;
|
|
VARIANT v;
|
|
HRESULT hret;
|
|
CIMTYPE type;
|
|
|
|
// Ok, start string manipulation.
|
|
|
|
// Read each line and glean the required information
|
|
CHAR sep[] = "\r\n";
|
|
PCHAR temp1;
|
|
|
|
PCHAR temp = strtok(data,sep);
|
|
int i = 0;
|
|
strcpy(red,"no"); // Put in the default values for these.
|
|
*pdelay = 30;
|
|
while(temp){
|
|
// Ignore spaces
|
|
while(*temp && *temp == ' '){
|
|
temp++;
|
|
}
|
|
if(*temp == ';'){// comment line
|
|
temp = strtok(NULL,sep);
|
|
continue;
|
|
}
|
|
if(strncmp(temp,"[boot loader]",strlen("[boot loader]"))==0){
|
|
do{
|
|
temp1 = strchr(temp,'=');
|
|
if(!temp1){
|
|
// weird stuff is going on
|
|
// could be a comment line or some such thing
|
|
temp = strtok(NULL,sep);
|
|
continue;
|
|
}
|
|
else{
|
|
temp1++;
|
|
}
|
|
while(*temp1 && *temp1 == ' ' ){
|
|
temp1++;
|
|
}
|
|
if(strncmp(temp,"default",strlen("default"))==0){
|
|
def= temp1;
|
|
temp = strtok(NULL,sep);
|
|
continue;
|
|
}
|
|
if(strncmp(temp,"redirect",strlen("redirect"))==0){
|
|
sscanf(temp1, "%s",red);
|
|
temp = strtok(NULL,sep);
|
|
continue;
|
|
}
|
|
if(strncmp(temp,"timeout=",strlen("timeout="))==0){
|
|
sscanf(temp1, "%d",pdelay);
|
|
}
|
|
temp = strtok(NULL,sep);
|
|
}while(temp && (*temp != '[')); // next section has begun
|
|
continue;
|
|
}
|
|
if(strncmp(temp,"[operating systems]",strlen("[operating systems]")) == 0){
|
|
bound[0].lLbound = 0;
|
|
bound[0].cElements = 0;
|
|
*psa = SafeArrayCreate(VT_UNKNOWN,
|
|
1,
|
|
bound
|
|
);
|
|
|
|
if(*psa == NULL){
|
|
return WBEM_E_FAILED;
|
|
}
|
|
do{
|
|
|
|
// Trim leading spaces
|
|
while (*temp == ' '){
|
|
temp ++;
|
|
}
|
|
// Skip comment lines
|
|
if ( *temp != ';' ){
|
|
// pChar will point at the directory
|
|
|
|
PCHAR pChar = strchr(temp,'=');
|
|
|
|
// We must have an = sign or this is an invalid string
|
|
|
|
if (pChar){
|
|
// Punch in a null
|
|
// Increase the number of elements
|
|
index = (long) bound[0].cElements;
|
|
bound[0].cElements += 1;
|
|
ret = SafeArrayRedim(*psa,
|
|
bound
|
|
);
|
|
if(ret != S_OK){
|
|
SafeArrayDestroy(*psa);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
sc = pClass->SpawnInstance(0,&pNewOSInst);
|
|
// Start filling in the new instance
|
|
if(FAILED(sc)){
|
|
SafeArrayDestroy(*psa);
|
|
return sc;
|
|
}
|
|
sc = ParseLine(pNewOSInst,temp,pChar);
|
|
if (sc != S_OK) {
|
|
SafeArrayDestroy(*psa);
|
|
return sc;
|
|
}
|
|
ret = SafeArrayPutElement(*psa,
|
|
&index,
|
|
pNewOSInst
|
|
);
|
|
if(ret != S_OK){
|
|
SafeArrayDestroy(*psa);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
}
|
|
}
|
|
temp = strtok(NULL,sep);
|
|
}while(temp && (*temp != '['));
|
|
}
|
|
}
|
|
|
|
// Now find out if the default operating system is in one of the
|
|
// Convert the default string to a proper displayable value.
|
|
if(def){
|
|
int size = strlen(def);
|
|
int len;
|
|
*wdef = (PWCHAR) BPAlloc((size+1)*sizeof(WCHAR));
|
|
|
|
if(*wdef == NULL){
|
|
SafeArrayDestroy(*psa);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
len = MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
def,
|
|
size,
|
|
*wdef,
|
|
size
|
|
);
|
|
(*wdef)[len] = (WCHAR) 0;
|
|
LONG uBound;
|
|
IWbemClassObject *pOSInst;
|
|
hret = SafeArrayGetUBound(*psa,
|
|
1,
|
|
&uBound
|
|
);
|
|
LONG i;
|
|
for(i = 0; i<=uBound; i++){
|
|
hret = SafeArrayGetElement(*psa,
|
|
&i,
|
|
&pOSInst
|
|
);
|
|
if(hret != S_OK){
|
|
pOSInst->Release();
|
|
SafeArrayDestroy(*psa);
|
|
BPFree(*wdef);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
hret = pOSInst->Get(L"Directory",
|
|
0,
|
|
&v,
|
|
&type,
|
|
NULL
|
|
);
|
|
if(hret != WBEM_S_NO_ERROR){
|
|
SafeArrayDestroy(*psa);
|
|
pOSInst->Release();
|
|
BPFree(*wdef);
|
|
return -1;
|
|
}
|
|
if(v.vt != VT_BSTR){
|
|
SafeArrayDestroy(*psa);
|
|
pOSInst->Release();
|
|
BPFree(*wdef);
|
|
return -1;
|
|
}
|
|
if(wcscmp(v.bstrVal,*wdef) == 0){
|
|
VariantClear(&v);
|
|
break;
|
|
}
|
|
}
|
|
BPFree(*wdef);
|
|
if(i > uBound){
|
|
SafeArrayDestroy(*psa);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
hret=pOSInst->Get(L"OperatingSystem",
|
|
0,
|
|
&v,
|
|
&type,
|
|
NULL
|
|
);
|
|
pOSInst->Release();
|
|
if(hret != WBEM_S_NO_ERROR){
|
|
SafeArrayDestroy(*psa);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
if(v.vt != VT_BSTR){
|
|
SafeArrayDestroy(*psa);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
*wdef = (PWCHAR) BPAlloc(wcslen(v.bstrVal) + sizeof(WCHAR));
|
|
if(*wdef == NULL){
|
|
return -1;
|
|
}
|
|
wcscpy(*wdef,v.bstrVal);
|
|
VariantClear(&v);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
SCODE
|
|
GetLoaderParameters(HANDLE BootFile,
|
|
IWbemClassObject *pNewInst,
|
|
IWbemClassObject *pClass
|
|
)
|
|
{
|
|
// Read the entire file into memory if you can otherwise forget about it.
|
|
VARIANT v;
|
|
LONG dwret;
|
|
SCODE sc;
|
|
DWORD dwlen;
|
|
|
|
|
|
DWORD dwsize = GetFileSize(BootFile,
|
|
NULL
|
|
);
|
|
if(dwsize == -1){
|
|
return WBEM_E_FAILED;
|
|
}
|
|
PCHAR data =(PCHAR) BPAlloc(dwsize + sizeof(CHAR));
|
|
if(!data){
|
|
return WBEM_E_FAILED;
|
|
}
|
|
dwret = ReadFile(BootFile,
|
|
(LPVOID) data,
|
|
dwsize,
|
|
&dwlen,
|
|
NULL
|
|
);
|
|
|
|
if(dwret == 0){
|
|
BPFree(data);
|
|
return GetLastError();
|
|
}
|
|
|
|
// Parse the code and return the answers in two arrays, and a safe array
|
|
SAFEARRAY *psa;
|
|
CHAR red[32];
|
|
LONG delay;
|
|
PWCHAR wdef=NULL;
|
|
sc = ParseBootFile(pClass,
|
|
data,
|
|
&wdef,
|
|
red,
|
|
&delay,
|
|
&psa
|
|
);
|
|
|
|
BPFree(data);
|
|
if (sc != S_OK) {
|
|
return sc;
|
|
}
|
|
|
|
// fill in the New Instance
|
|
|
|
// Fill in the default OS.
|
|
v.vt = VT_BSTR;
|
|
int len;
|
|
v.bstrVal = SysAllocString(wdef);
|
|
sc = pNewInst->Put(L"Default", 0,&v, 0);
|
|
VariantClear(&v);
|
|
BPFree(wdef);
|
|
|
|
//Fill in the redirect parameter
|
|
WCHAR wred[32];
|
|
len = MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
red,
|
|
strlen(red),
|
|
wred,
|
|
32
|
|
);
|
|
wred[len] = (WCHAR) 0;
|
|
v.vt = VT_BSTR;
|
|
v.bstrVal = SysAllocString(wred);
|
|
sc = pNewInst->Put(L"Redirect", 0, &v, 0);
|
|
VariantClear(&v);
|
|
|
|
// Fill in the delay
|
|
|
|
v.vt = VT_I4;
|
|
v.lVal = delay;
|
|
sc = pNewInst->Put(L"Delay", 0, &v, 0);
|
|
VariantClear(&v);
|
|
|
|
// Fill in the OS in the file
|
|
v.vt = VT_ARRAY|VT_UNKNOWN;
|
|
v.parray = psa;
|
|
sc = pNewInst->Put(L"operating_systems", 0, &v, 0);
|
|
VariantClear(&v);
|
|
return S_OK;
|
|
}
|
|
|
|
//BOOLEAN first=TRUE;
|
|
|
|
SCODE
|
|
GetBootLoaderParameters(IWbemServices * m_pNamespace,
|
|
IWbemClassObject *pNewInst,
|
|
IWbemContext *pCtx
|
|
)
|
|
{
|
|
HANDLE BootFile;
|
|
SCODE sc;
|
|
IWbemClassObject *pClass;
|
|
IWbemObjectTextSrc *pSrc;
|
|
BSTR strText;
|
|
HRESULT hr;
|
|
/*
|
|
if (first) {
|
|
first = FALSE;
|
|
return WBEM_E_FAILED;
|
|
}
|
|
*/
|
|
// Read the file and set in the values.
|
|
if(pNewInst == NULL){
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
// Get a handle to the boot file.
|
|
PCHAR data = GetBootFileName();
|
|
if(!data){
|
|
return WBEM_E_FAILED;
|
|
}
|
|
BootFile = GetFileHandle(data,OPEN_EXISTING,GENERIC_READ);
|
|
BPFree(data);
|
|
if(BootFile == INVALID_HANDLE_VALUE){
|
|
return WBEM_E_FAILED;
|
|
}
|
|
sc = m_pNamespace->GetObject(L"OSParameters", 0, pCtx, &pClass, NULL);
|
|
if (sc != S_OK) {
|
|
return WBEM_E_FAILED;
|
|
}
|
|
sc = GetLoaderParameters(BootFile, pNewInst, pClass);
|
|
CloseHandle(BootFile);
|
|
pClass->Release();
|
|
if (sc != S_OK) {
|
|
return WBEM_E_FAILED;
|
|
}
|
|
|
|
pSrc = NULL;
|
|
IWbemClassObject *pInstance;
|
|
|
|
if(SUCCEEDED(hr = CoCreateInstance (CLSID_WbemObjectTextSrc, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IWbemObjectTextSrc, (void**) &pSrc))) {
|
|
if (pSrc) {
|
|
if(SUCCEEDED(hr = pSrc->GetText(0, pNewInst, WMI_OBJ_TEXT_WMI_DTD_2_0, pCtx, &strText))) {
|
|
if( SUCCEEDED( hr = pSrc->CreateFromText( 0, strText, WMI_OBJ_TEXT_WMI_DTD_2_0,
|
|
NULL, &pInstance) ) ) {
|
|
pInstance->Release();
|
|
sc = 0;
|
|
} else {
|
|
sc = hr;
|
|
}
|
|
SysFreeString(strText);
|
|
}
|
|
else {
|
|
printf("GetText failed with %x\n", hr);
|
|
}
|
|
pSrc->Release();
|
|
}
|
|
|
|
}
|
|
else
|
|
printf("CoCreateInstance on WbemObjectTextSrc failed with %x\n", hr);
|
|
|
|
return sc;
|
|
}
|