Leaked source code of windows server 2003
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.

534 lines
16 KiB

  1. //***************************************************************************
  2. //
  3. // getparams.cpp
  4. //
  5. // Module: WMI Instance provider code for boot parameters
  6. //
  7. // Purpose: Extracting boot parameters.
  8. //
  9. // Copyright (c) 1997-1999 Microsoft Corporation
  10. //
  11. //***************************************************************************
  12. #include "bootini.h"
  13. SCODE ParseLine(IWbemClassObject *pNewOSInst,
  14. PCHAR line,
  15. PCHAR options
  16. )
  17. {
  18. PCHAR rest; // the rest of the options cannot be bigger than this.
  19. int size = strlen(line);
  20. int len;
  21. SCODE sc;
  22. VARIANT v;
  23. BOOL found=FALSE;
  24. rest = (PCHAR) BPAlloc(size);
  25. if (!rest) {
  26. return WBEM_E_FAILED;
  27. }
  28. PWCHAR wstr;
  29. wstr = (PWCHAR) BPAlloc(size*sizeof(WCHAR));
  30. if (!wstr) {
  31. BPFree(rest);
  32. return WBEM_E_FAILED;
  33. }
  34. *options = 0; //Later fill in the '='
  35. len = MultiByteToWideChar(CP_ACP,
  36. 0,
  37. line,
  38. strlen(line),
  39. wstr,
  40. size
  41. );
  42. wstr[len] = (WCHAR) 0;
  43. v.vt = VT_BSTR;
  44. v.bstrVal = SysAllocString(wstr);
  45. sc = pNewOSInst->Put(L"Directory", 0,&v, 0);
  46. VariantClear(&v);
  47. PCHAR temp = options + 1;
  48. *options = '=';
  49. PCHAR temp1;
  50. // Rest of the stuff is filled in during initialization
  51. while(*temp){ // We know line ends with a null
  52. while(*temp && *temp == ' '){
  53. temp ++;
  54. }
  55. if(*temp == 0) break;
  56. // Get the new string
  57. temp1 = temp;
  58. if(*temp == '"'){
  59. // could be the name of the OS
  60. do {
  61. temp1++;
  62. }while(*temp1 && (*temp1 != '"'));
  63. if(*temp1){
  64. temp1++;
  65. }
  66. else{
  67. BPFree(rest);
  68. BPFree(wstr);
  69. return WBEM_E_FAILED;
  70. }
  71. len = MultiByteToWideChar(CP_ACP,
  72. 0,
  73. temp,
  74. temp1-temp,
  75. wstr,
  76. size
  77. );
  78. wstr[len] = (WCHAR) 0;
  79. v.vt = VT_BSTR;
  80. v.bstrVal = SysAllocString(wstr);
  81. sc = pNewOSInst->Put(L"OperatingSystem", 0,&v, 0);
  82. VariantClear(&v);
  83. temp = temp1;
  84. continue;
  85. }
  86. do{
  87. temp1++;
  88. }while((*temp1) && (*temp1 != ' ') && (*temp1 != '/'));
  89. // Now we have the option between temp1 and temp2.
  90. if(strncmp(temp,"/redirect", strlen("/redirect")) == 0){
  91. v.vt = VT_BOOL;
  92. v.boolVal = TRUE;
  93. sc = pNewOSInst->Put(L"Redirect", 0,&v, 0);
  94. VariantClear(&v);
  95. temp = temp1;
  96. continue;
  97. }
  98. if(strncmp(temp,"/debug", strlen("/debug")) == 0){
  99. // fill in the redirect flag.
  100. v.vt = VT_BOOL;
  101. v.boolVal = TRUE;
  102. sc = pNewOSInst->Put(L"Debug", 0,&v, 0);
  103. VariantClear(&v);
  104. temp = temp1;
  105. continue;
  106. }
  107. if(strncmp(temp,"/fastdetect", strlen("/fastdetect")) == 0){
  108. // fill in the redirect flag.
  109. v.vt = VT_BOOL;
  110. v.boolVal = TRUE;
  111. sc = pNewOSInst->Put(L"Fastdetect", 0,&v, 0);
  112. VariantClear(&v);
  113. temp = temp1;
  114. continue;
  115. }
  116. strncat(rest,temp, temp1-temp);
  117. strcat(rest," ");
  118. temp = temp1;
  119. }
  120. len = MultiByteToWideChar(CP_ACP,
  121. 0,
  122. rest,
  123. strlen(rest),
  124. wstr,
  125. size
  126. );
  127. wstr[len] = (WCHAR) 0;
  128. v.vt=VT_BSTR;
  129. v.bstrVal = SysAllocString(wstr);
  130. sc = pNewOSInst->Put(L"Rest", 0,&v, 0);
  131. VariantClear(&v);
  132. BPFree(rest);
  133. BPFree(wstr);
  134. return sc;
  135. }
  136. SCODE
  137. ParseBootFile(IWbemClassObject *pClass,
  138. PCHAR data,
  139. PWCHAR *wdef,
  140. PCHAR red,
  141. PLONG pdelay,
  142. SAFEARRAY **psa
  143. )
  144. {
  145. IWbemClassObject FAR* pNewOSInst;
  146. HRESULT ret;
  147. int dwRet;
  148. SCODE sc;
  149. SAFEARRAYBOUND bound[1];
  150. long index;
  151. PCHAR def=NULL;
  152. PCHAR pChar;
  153. VARIANT v;
  154. HRESULT hret;
  155. CIMTYPE type;
  156. // Ok, start string manipulation.
  157. // Read each line and glean the required information
  158. CHAR sep[] = "\r\n";
  159. PCHAR temp1;
  160. PCHAR temp = strtok(data,sep);
  161. int i = 0;
  162. strcpy(red,"no"); // Put in the default values for these.
  163. *pdelay = 30;
  164. while(temp){
  165. // Ignore spaces
  166. while(*temp && *temp == ' '){
  167. temp++;
  168. }
  169. if(*temp == ';'){// comment line
  170. temp = strtok(NULL,sep);
  171. continue;
  172. }
  173. if(strncmp(temp,"[boot loader]",strlen("[boot loader]"))==0){
  174. do{
  175. temp1 = strchr(temp,'=');
  176. if(!temp1){
  177. // weird stuff is going on
  178. // could be a comment line or some such thing
  179. temp = strtok(NULL,sep);
  180. continue;
  181. }
  182. else{
  183. temp1++;
  184. }
  185. while(*temp1 && *temp1 == ' ' ){
  186. temp1++;
  187. }
  188. if(strncmp(temp,"default",strlen("default"))==0){
  189. def= temp1;
  190. temp = strtok(NULL,sep);
  191. continue;
  192. }
  193. if(strncmp(temp,"redirect",strlen("redirect"))==0){
  194. sscanf(temp1, "%s",red);
  195. temp = strtok(NULL,sep);
  196. continue;
  197. }
  198. if(strncmp(temp,"timeout=",strlen("timeout="))==0){
  199. sscanf(temp1, "%d",pdelay);
  200. }
  201. temp = strtok(NULL,sep);
  202. }while(temp && (*temp != '[')); // next section has begun
  203. continue;
  204. }
  205. if(strncmp(temp,"[operating systems]",strlen("[operating systems]")) == 0){
  206. bound[0].lLbound = 0;
  207. bound[0].cElements = 0;
  208. *psa = SafeArrayCreate(VT_UNKNOWN,
  209. 1,
  210. bound
  211. );
  212. if(*psa == NULL){
  213. return WBEM_E_FAILED;
  214. }
  215. do{
  216. // Trim leading spaces
  217. while (*temp == ' '){
  218. temp ++;
  219. }
  220. // Skip comment lines
  221. if ( *temp != ';' ){
  222. // pChar will point at the directory
  223. PCHAR pChar = strchr(temp,'=');
  224. // We must have an = sign or this is an invalid string
  225. if (pChar){
  226. // Punch in a null
  227. // Increase the number of elements
  228. index = (long) bound[0].cElements;
  229. bound[0].cElements += 1;
  230. ret = SafeArrayRedim(*psa,
  231. bound
  232. );
  233. if(ret != S_OK){
  234. SafeArrayDestroy(*psa);
  235. return WBEM_E_FAILED;
  236. }
  237. sc = pClass->SpawnInstance(0,&pNewOSInst);
  238. // Start filling in the new instance
  239. if(FAILED(sc)){
  240. SafeArrayDestroy(*psa);
  241. return sc;
  242. }
  243. sc = ParseLine(pNewOSInst,temp,pChar);
  244. if (sc != S_OK) {
  245. SafeArrayDestroy(*psa);
  246. return sc;
  247. }
  248. ret = SafeArrayPutElement(*psa,
  249. &index,
  250. pNewOSInst
  251. );
  252. if(ret != S_OK){
  253. SafeArrayDestroy(*psa);
  254. return WBEM_E_FAILED;
  255. }
  256. }
  257. }
  258. temp = strtok(NULL,sep);
  259. }while(temp && (*temp != '['));
  260. }
  261. }
  262. // Now find out if the default operating system is in one of the
  263. // Convert the default string to a proper displayable value.
  264. if(def){
  265. int size = strlen(def);
  266. int len;
  267. *wdef = (PWCHAR) BPAlloc((size+1)*sizeof(WCHAR));
  268. if(*wdef == NULL){
  269. SafeArrayDestroy(*psa);
  270. return WBEM_E_FAILED;
  271. }
  272. len = MultiByteToWideChar(CP_ACP,
  273. 0,
  274. def,
  275. size,
  276. *wdef,
  277. size
  278. );
  279. (*wdef)[len] = (WCHAR) 0;
  280. LONG uBound;
  281. IWbemClassObject *pOSInst;
  282. hret = SafeArrayGetUBound(*psa,
  283. 1,
  284. &uBound
  285. );
  286. LONG i;
  287. for(i = 0; i<=uBound; i++){
  288. hret = SafeArrayGetElement(*psa,
  289. &i,
  290. &pOSInst
  291. );
  292. if(hret != S_OK){
  293. pOSInst->Release();
  294. SafeArrayDestroy(*psa);
  295. BPFree(*wdef);
  296. return WBEM_E_FAILED;
  297. }
  298. hret = pOSInst->Get(L"Directory",
  299. 0,
  300. &v,
  301. &type,
  302. NULL
  303. );
  304. if(hret != WBEM_S_NO_ERROR){
  305. SafeArrayDestroy(*psa);
  306. pOSInst->Release();
  307. BPFree(*wdef);
  308. return -1;
  309. }
  310. if(v.vt != VT_BSTR){
  311. SafeArrayDestroy(*psa);
  312. pOSInst->Release();
  313. BPFree(*wdef);
  314. return -1;
  315. }
  316. if(wcscmp(v.bstrVal,*wdef) == 0){
  317. VariantClear(&v);
  318. break;
  319. }
  320. }
  321. BPFree(*wdef);
  322. if(i > uBound){
  323. SafeArrayDestroy(*psa);
  324. return WBEM_E_FAILED;
  325. }
  326. hret=pOSInst->Get(L"OperatingSystem",
  327. 0,
  328. &v,
  329. &type,
  330. NULL
  331. );
  332. pOSInst->Release();
  333. if(hret != WBEM_S_NO_ERROR){
  334. SafeArrayDestroy(*psa);
  335. return WBEM_E_FAILED;
  336. }
  337. if(v.vt != VT_BSTR){
  338. SafeArrayDestroy(*psa);
  339. return WBEM_E_FAILED;
  340. }
  341. *wdef = (PWCHAR) BPAlloc(wcslen(v.bstrVal) + sizeof(WCHAR));
  342. if(*wdef == NULL){
  343. return -1;
  344. }
  345. wcscpy(*wdef,v.bstrVal);
  346. VariantClear(&v);
  347. }
  348. return S_OK;
  349. }
  350. SCODE
  351. GetLoaderParameters(HANDLE BootFile,
  352. IWbemClassObject *pNewInst,
  353. IWbemClassObject *pClass
  354. )
  355. {
  356. // Read the entire file into memory if you can otherwise forget about it.
  357. VARIANT v;
  358. LONG dwret;
  359. SCODE sc;
  360. DWORD dwlen;
  361. DWORD dwsize = GetFileSize(BootFile,
  362. NULL
  363. );
  364. if(dwsize == -1){
  365. return WBEM_E_FAILED;
  366. }
  367. PCHAR data =(PCHAR) BPAlloc(dwsize + sizeof(CHAR));
  368. if(!data){
  369. return WBEM_E_FAILED;
  370. }
  371. dwret = ReadFile(BootFile,
  372. (LPVOID) data,
  373. dwsize,
  374. &dwlen,
  375. NULL
  376. );
  377. if(dwret == 0){
  378. BPFree(data);
  379. return GetLastError();
  380. }
  381. // Parse the code and return the answers in two arrays, and a safe array
  382. SAFEARRAY *psa;
  383. CHAR red[32];
  384. LONG delay;
  385. PWCHAR wdef=NULL;
  386. sc = ParseBootFile(pClass,
  387. data,
  388. &wdef,
  389. red,
  390. &delay,
  391. &psa
  392. );
  393. BPFree(data);
  394. if (sc != S_OK) {
  395. return sc;
  396. }
  397. // fill in the New Instance
  398. // Fill in the default OS.
  399. v.vt = VT_BSTR;
  400. int len;
  401. v.bstrVal = SysAllocString(wdef);
  402. sc = pNewInst->Put(L"Default", 0,&v, 0);
  403. VariantClear(&v);
  404. BPFree(wdef);
  405. //Fill in the redirect parameter
  406. WCHAR wred[32];
  407. len = MultiByteToWideChar(CP_ACP,
  408. 0,
  409. red,
  410. strlen(red),
  411. wred,
  412. 32
  413. );
  414. wred[len] = (WCHAR) 0;
  415. v.vt = VT_BSTR;
  416. v.bstrVal = SysAllocString(wred);
  417. sc = pNewInst->Put(L"Redirect", 0, &v, 0);
  418. VariantClear(&v);
  419. // Fill in the delay
  420. v.vt = VT_I4;
  421. v.lVal = delay;
  422. sc = pNewInst->Put(L"Delay", 0, &v, 0);
  423. VariantClear(&v);
  424. // Fill in the OS in the file
  425. v.vt = VT_ARRAY|VT_UNKNOWN;
  426. v.parray = psa;
  427. sc = pNewInst->Put(L"operating_systems", 0, &v, 0);
  428. VariantClear(&v);
  429. return S_OK;
  430. }
  431. //BOOLEAN first=TRUE;
  432. SCODE
  433. GetBootLoaderParameters(IWbemServices * m_pNamespace,
  434. IWbemClassObject *pNewInst,
  435. IWbemContext *pCtx
  436. )
  437. {
  438. HANDLE BootFile;
  439. SCODE sc;
  440. IWbemClassObject *pClass;
  441. IWbemObjectTextSrc *pSrc;
  442. BSTR strText;
  443. HRESULT hr;
  444. /*
  445. if (first) {
  446. first = FALSE;
  447. return WBEM_E_FAILED;
  448. }
  449. */
  450. // Read the file and set in the values.
  451. if(pNewInst == NULL){
  452. return WBEM_E_INVALID_PARAMETER;
  453. }
  454. // Get a handle to the boot file.
  455. PCHAR data = GetBootFileName();
  456. if(!data){
  457. return WBEM_E_FAILED;
  458. }
  459. BootFile = GetFileHandle(data,OPEN_EXISTING,GENERIC_READ);
  460. BPFree(data);
  461. if(BootFile == INVALID_HANDLE_VALUE){
  462. return WBEM_E_FAILED;
  463. }
  464. sc = m_pNamespace->GetObject(L"OSParameters", 0, pCtx, &pClass, NULL);
  465. if (sc != S_OK) {
  466. return WBEM_E_FAILED;
  467. }
  468. sc = GetLoaderParameters(BootFile, pNewInst, pClass);
  469. CloseHandle(BootFile);
  470. pClass->Release();
  471. if (sc != S_OK) {
  472. return WBEM_E_FAILED;
  473. }
  474. pSrc = NULL;
  475. IWbemClassObject *pInstance;
  476. if(SUCCEEDED(hr = CoCreateInstance (CLSID_WbemObjectTextSrc, NULL, CLSCTX_INPROC_SERVER,
  477. IID_IWbemObjectTextSrc, (void**) &pSrc))) {
  478. if (pSrc) {
  479. if(SUCCEEDED(hr = pSrc->GetText(0, pNewInst, WMI_OBJ_TEXT_WMI_DTD_2_0, pCtx, &strText))) {
  480. if( SUCCEEDED( hr = pSrc->CreateFromText( 0, strText, WMI_OBJ_TEXT_WMI_DTD_2_0,
  481. NULL, &pInstance) ) ) {
  482. pInstance->Release();
  483. sc = 0;
  484. } else {
  485. sc = hr;
  486. }
  487. SysFreeString(strText);
  488. }
  489. else {
  490. printf("GetText failed with %x\n", hr);
  491. }
  492. pSrc->Release();
  493. }
  494. }
  495. else
  496. printf("CoCreateInstance on WbemObjectTextSrc failed with %x\n", hr);
  497. return sc;
  498. }