Source code of Windows XP (NT5)
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.

1249 lines
34 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <tchar.h>
  4. #include <winver.h>
  5. #include "network.h"
  6. #include "idw_dbg.h"
  7. #include "machines.h"
  8. #include "files.h"
  9. //#include <setupapi.h>
  10. /*++
  11. Filename : Files.c
  12. Description: Contains the network access code.
  13. Created by: Wally Ho
  14. History: Created on 20/02/2000.
  15. 09.19.2001 Joe Holman fixes for idwlog bugs 409338, 399178, and 352810
  16. Contains these functions:
  17. 1. BOOL GetCurrentSystemBuildInfo ( IN OUT LPINSTALL_DATA pId);
  18. 2. BOOL GetCurrentInstallingBuildInfo ( IN OUT LPINSTALL_DATA pId);
  19. 3. BOOL GetImageHlpDllInfo ( OUT LPINSTALL_DATA pId,
  20. IN INT iFlag);
  21. 4. BOOL MyGetFileVersionInfo(LPTSTR lpszFilename,
  22. LPVOID *lpVersionInfo);
  23. 5. BOOL GetSkuFromDosNetInf (IN OUT LPINSTALL_DATA pId);
  24. 03.29.2001 Joe Holman Made the code work on Win9x.
  25. --*/
  26. DWORD gdwLength; // global used for Win9x data mining, length of buffer.
  27. BOOL
  28. GetCurrentSystemBuildInfo ( IN OUT LPINSTALL_DATA pId)
  29. /*++
  30. Routine Description:
  31. This loads the three items of
  32. DWORD dwSystemBuild;
  33. DWORD dwSystemBuildDelta;
  34. TCHAR szSystemBuildSourceLocation[100]
  35. From information gleaned from the imagehlp.dll.
  36. *NOTE*
  37. The ImageHlp.dll according to Micheal Lekas is compiled everytime a
  38. build is put out. We are banking on this for this function.
  39. For XP SPs, this will be from the ntoskrnl.exe file.
  40. Arguments:
  41. An Install Data struct for loading the data.
  42. Return Value:
  43. TRUE if success
  44. FALSE if fail
  45. --*/
  46. {
  47. //Initialize all the variables first to expected values.
  48. pId->dwSystemBuild = 0;
  49. pId->dwSystemBuildDelta = 0;
  50. pId->dwSystemSPBuild = 0;
  51. pId->dwSystemMajorVersion = 0;
  52. pId->dwSystemMinorVersion = 0;
  53. _stprintf(pId->szSystemBuildSourceLocation, TEXT("%s"),
  54. TEXT("No_Build_Lab_Information"));
  55. if (DTC == TRUE){
  56. if (FALSE == GetBuildInfoFromOSAndBldFile(pId, F_SYSTEM )){
  57. Idwlog(TEXT("GetBuildInfoFromOSAndBldFile failed. Could not retrieved build, delta, location.\n"));
  58. return FALSE;
  59. }else{
  60. Idwlog(TEXT("Success in retrieving build, delta, location.\n"));
  61. return TRUE;
  62. }
  63. // This is Whistler.
  64. }else{
  65. if (FALSE == GetImageHlpDllInfo(pId, F_SYSTEM_IMAGEHLP_DLL)){
  66. Idwlog(TEXT("GetImageHlpDllInfo failed. Could not retrieved build, delta, location.\n"));
  67. return FALSE;
  68. }else{
  69. Idwlog(TEXT("Success in retrieving build, delta, location.\n"));
  70. return TRUE;
  71. }
  72. }
  73. }
  74. BOOL
  75. GetCurrentInstallingBuildInfo ( IN OUT LPINSTALL_DATA pId)
  76. /*++
  77. Routine Description:
  78. This loads the three items of
  79. DWORD dwInstallingBuild;
  80. DWORD dwInstallingBuildDelta;
  81. TCHAR szCurrentBuildSourceLocation[100];
  82. From information gleaned from the imagehlp.dll.
  83. *NOTE*
  84. The ImageHlp.dll according to Micheal Lekas is compiled everytime a
  85. build is put out. We are banking on this for this function.
  86. Arguments:
  87. An Install Data struct for loading the data.
  88. Return Value:
  89. TRUE if success
  90. FALSE if fail
  91. --*/
  92. {
  93. //Initialize all the variables first to expected values.
  94. pId->dwInstallingBuild = 0;
  95. pId->dwInstallingBuildDelta = 0;
  96. pId->dwInstallingSPBuild = 0;
  97. pId->dwInstallingMajorVersion = 0;
  98. pId->dwInstallingMinorVersion = 0;
  99. _stprintf(pId->szInstallingBuildSourceLocation, TEXT("%s"),
  100. TEXT("No_Build_Lab_Information"));
  101. if (DTC == 1){
  102. if (FALSE == GetBuildInfoFromOSAndBldFile(pId, F_INSTALLING )){
  103. Idwlog(TEXT("GetBuildInfoFromOSAndBldFile failed. Could not retrieved build, delta, location.\n"));
  104. return FALSE;
  105. }else{
  106. Idwlog(TEXT("Success in retrieving build, delta, location.\n"));
  107. return TRUE;
  108. }
  109. }else{
  110. if (FALSE == GetImageHlpDllInfo(pId, F_INSTALLING_IMAGEHLP_DLL )){
  111. Idwlog(TEXT("GetImageHlpDllInfo failed. Could not retrieved build, delta, location.\n"));
  112. return FALSE;
  113. }else{
  114. Idwlog(TEXT("Success in retrieving build, delta, location.\n"));
  115. return TRUE;
  116. }
  117. }
  118. }
  119. BOOL
  120. GetBuildInfoFromOSAndBldFile( OUT LPINSTALL_DATA pId,
  121. IN INT iFlag)
  122. /*++
  123. Routine Description:
  124. This loads the three items of
  125. DWORD dwInstallingBuild;
  126. DWORD dwInstallingBuildDelta;
  127. TCHAR szCurrentBuildSourceLocation[100];
  128. From information gleaned from the OS and the BLD file.
  129. *NOTE*
  130. This is assuming the changes of having the bld files on
  131. the CD in the same dir as the idwlog.exe and in the x86 share in on the server.
  132. Arguments:
  133. These flags are.
  134. F_SYSTEM 0x1
  135. F_INSTALLING 0x2
  136. Return Value:
  137. TRUE if success
  138. FALSE if fail
  139. --*/
  140. {
  141. WIN32_FIND_DATA fd;
  142. HANDLE hFind;
  143. TCHAR szFullPath [ MAX_PATH ];
  144. TCHAR szCurDir [ MAX_PATH ];
  145. LPTSTR ptstr;
  146. OSVERSIONINFO osex;
  147. DWORD dwLength = MAX_PATH;
  148. DWORD dwBuild;
  149. DWORD dwBuildDelta;
  150. TCHAR szDontCare[30];
  151. DWORD dwDontCare;
  152. szCurDir[0] = TEXT('\0');
  153. switch (iFlag){
  154. case F_INSTALLING:
  155. // Get the installing files location of the 2195.0XX.bld file
  156. GetModuleFileName( NULL,szCurDir, dwLength);
  157. // Remove the Idwlog.exe part and get only the directory structure.
  158. ptstr = _tcsrchr(szCurDir,TEXT('\\'));
  159. if (NULL == ptstr) {
  160. Idwlog(TEXT("ERROR GetBuildInfoFromOSAndBldFile could find the file to get bld info from.\n"));
  161. return FALSE;
  162. }
  163. *ptstr = TEXT('\0');
  164. Idwlog(TEXT("Getting Build, Delta, Build lab for the installing files.\n"));
  165. Idwlog(TEXT("Getting Installing file location as %s.\n"), szCurDir);
  166. // Use this to get the location
  167. // idwlog.exe -1 is run from. This tool
  168. // will always assume the 2195.xxx.bld is in its
  169. // current path or two up.
  170. _stprintf (szFullPath, TEXT("%s\\*.bld"),szCurDir);
  171. Idwlog(TEXT("First look for the XXXX.xxx.bld in [CD location] %s.\n"),
  172. szFullPath);
  173. // On a network share the 2195.xxx.bld is two up from where
  174. // idwlog.exe -1 is located.
  175. // On a CD its located in the same directory as where the
  176. // idwlog.exe -1 is located. We will look in both places.
  177. hFind = FindFirstFile (szFullPath, &fd);
  178. if (INVALID_HANDLE_VALUE == hFind){
  179. //
  180. // Now we know the file in not in the
  181. // immediate directory. Move up another 2 levels by
  182. // culling off two more directory.
  183. //
  184. for (INT i = 0; i < 2; i++) {
  185. ptstr = _tcsrchr(szCurDir,TEXT('\\'));
  186. if (NULL == ptstr) {
  187. Idwlog(TEXT("ERROR GetBuildInfoFromOSAndBldFile could not find the file to get bld info from.\n"));
  188. return FALSE;
  189. }
  190. *ptstr = TEXT('\0');
  191. }
  192. _stprintf (szFullPath, TEXT("%s\\*.bld"),szCurDir);
  193. Idwlog(TEXT("Second look for the XXXX.xxx.bld in [NET location] %s.\n"),
  194. szFullPath);
  195. hFind = FindFirstFile (szFullPath,&fd);
  196. if (INVALID_HANDLE_VALUE == hFind){
  197. // In case we cannot find it we will exit.
  198. // Set the currentBuild number to 0;
  199. //_tcscpy (id.szCurrentBuild, TEXT("latest"));
  200. Idwlog(TEXT("Could not find the XXXX.xxx.bld file in %s.\n"),
  201. szFullPath);
  202. Idwlog(TEXT("ERROR - Cannot get build number or delta of the installing build.\n"));
  203. return FALSE;
  204. }
  205. }
  206. _stscanf(fd.cFileName,TEXT("%lu.%lu.%s"),&dwBuild, &dwBuildDelta,szDontCare);
  207. Idwlog(TEXT("Inserting into struct Build, Delta, Build lab for the installing files.\n"));
  208. // Build Location
  209. _tcscpy( pId->szInstallingBuildSourceLocation,TEXT("No_Build_Lab_Information"));
  210. // Major version X.51
  211. pId->dwInstallingMajorVersion = 0;
  212. // Minor version 5.XX
  213. pId->dwInstallingMinorVersion = 0;
  214. // Build
  215. pId->dwInstallingBuild = dwBuild;
  216. // Build Delta.
  217. pId->dwInstallingBuildDelta = dwBuildDelta;
  218. pId->dwInstallingSPBuild = dwBuildDelta;
  219. if ( pId->dwInstallingMajorVersion == 0 || pId->dwInstallingMinorVersion == 0 ) {
  220. Idwlog(TEXT("GetBuildInfoFromOSAndBldFile F_INSTALLING ERROR - need Major or Minor #\n"));
  221. }
  222. Idwlog(TEXT("GetBuildInfoFromOSAndBldFile F_INSTALLING - Build = %ld, Major = %ld, Minor = %ld.\n"),
  223. pId->dwInstallingBuild,
  224. pId->dwInstallingMajorVersion,
  225. pId->dwInstallingMinorVersion
  226. );
  227. break;
  228. case F_SYSTEM:
  229. osex.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  230. GetVersionEx(&osex);
  231. // The output is like "RC 0.31"
  232. _stscanf(osex.szCSDVersion, TEXT("%s %lu.%lu"),
  233. szDontCare, &dwDontCare, &dwBuildDelta);
  234. // Get the local systems location of the imagehlp.dll
  235. Idwlog(TEXT("Inserting into struct Build, Delta, Build lab for the local system.\n"));
  236. // Build Location
  237. _tcscpy( pId->szSystemBuildSourceLocation,TEXT("No_Build_Lab_Information"));
  238. // Major version X.51
  239. pId->dwSystemMajorVersion = 0;
  240. // Minor version 5.XX
  241. pId->dwSystemMinorVersion = 0;
  242. // Build
  243. pId->dwSystemBuild = osex.dwBuildNumber;
  244. // Build Delta.
  245. pId->dwSystemBuildDelta = dwBuildDelta;
  246. pId->dwSystemSPBuild = dwBuildDelta;
  247. Idwlog(TEXT("Getting Build, Delta, Build lab for local system.\n"));
  248. if ( pId->dwInstallingMajorVersion == 0 || pId->dwInstallingMinorVersion == 0 ) {
  249. Idwlog(TEXT("GetBuildInfoFromOSAndBldFile F_SYSTEM ERROR - need Major or Minor #\n"));
  250. }
  251. Idwlog(TEXT("GetBuildInfoFromOSAndBldFile F_SYSTEM - Build = %ld, Major = %ld, Minor = %ld.\n"),
  252. pId->dwInstallingBuild,
  253. pId->dwInstallingMajorVersion,
  254. pId->dwInstallingMinorVersion
  255. );
  256. break;
  257. }
  258. return TRUE;
  259. }
  260. BOOL
  261. GetImageHlpDllInfo ( OUT LPINSTALL_DATA pId,
  262. IN INT iFlag)
  263. /*++
  264. Routine Description:
  265. This loads the three items of
  266. DWORD dwInstallingBuild;
  267. DWORD dwInstallingBuildDelta;
  268. TCHAR szCurrentBuildSourceLocation[100];
  269. From information gleaned from the imagehlp.dll.
  270. *NOTE*
  271. The ImageHlp.dll according to Micheal Lekas is compiled everytime a
  272. build is put out. We are banking on this for this function.
  273. Arguments:
  274. An Install Data struct and the Imagehelp DLL location.
  275. It so it can be reused for both local probing and
  276. Installation probing.
  277. iFlag for System Probe or Installing Probe.
  278. Also if we want the data from imagehlp.dll or from the
  279. System. These flags are.
  280. F_SYSTEM_IMAGEHLP_DLL 0x1
  281. F_INSTALLING_IMAGEHLP_DLL 0x2
  282. Return Value:
  283. TRUE if success
  284. FALSE if fail
  285. --*/
  286. {
  287. VS_FIXEDFILEINFO* pv;
  288. WIN32_FIND_DATA fd;
  289. HANDLE hFind;
  290. TCHAR szFullPath [ MAX_PATH ] = "\0";
  291. TCHAR szCurDir [ MAX_PATH ] = "\0";
  292. TCHAR szBuildLocation[ MAX_PATH ] = "\0";
  293. TCHAR szTempDir [ MAX_PATH ] = "\0";
  294. TCHAR szTempDirFile [ MAX_PATH ] = "\0";
  295. DWORD dwError = 0;
  296. LPTSTR ptstr;
  297. DWORD dwTemp;
  298. BOOL b;
  299. LPVOID lpData = NULL;
  300. LPVOID lpInfo = NULL;
  301. TCHAR key[80];
  302. DWORD *pdwTranslation;
  303. UINT cch, uLen;
  304. DWORD dwDefLang = 0x40904b0;
  305. DWORD dwLength = MAX_PATH;
  306. CHAR *p = NULL;
  307. DWORD dwHandle;
  308. Idwlog ( TEXT ( "GetImageHlpDllInfo - entered.\n") );
  309. szCurDir[0] = TEXT('\0');
  310. // Configure the path to the where the image file lives.
  311. // This is different for the currently installed system vs. the installing build during -1.
  312. // However, for -3, it's a no-op, since we are installed and logged in.
  313. //
  314. // If we are in phase 3, we switch where the path points to.
  315. //
  316. if ( g_InstallData.bSPUninst || g_InstallData.bSPPatch || g_InstallData.bSPFull || g_InstallData.bSPUpdate ) {
  317. // New code to work with SPs.
  318. //
  319. if (iFlag == F_INSTALLING_IMAGEHLP_DLL && (g_InstallData.iStageSequence == 3 || g_InstallData.iStageSequence == 2) ) {
  320. iFlag = F_SYSTEM_IMAGEHLP_DLL;
  321. }
  322. switch (iFlag){
  323. case F_INSTALLING_IMAGEHLP_DLL:
  324. // Get the image data for the build that we are installing.
  325. p = _tcsstr (GetCommandLine(), TEXT("Path="));
  326. if ( p == NULL ) {
  327. Idwlog ( TEXT ( "GetImageHlpDllInfo ERROR - Could not determine path from command line, you need a Path=<path to the installing build> with trailing slash.\n") );
  328. return(FALSE);
  329. }
  330. p += _tcsclen ( TEXT ("Path=" ) );
  331. // We now have the location of the file to expand.
  332. //
  333. //_stprintf (szCurDir, TEXT("%s\\system32\\idwlog.exe"),p);
  334. _stprintf (szFullPath, TEXT("%s\\imagehlp.dll"),p);
  335. /*****
  336. // Get a temporary location to expand the file.
  337. // Can use this if the file is compressed from the media. This will NOT work on Win9x though (setupapi).
  338. //
  339. //
  340. dwError = GetTempPath ( MAX_PATH, szTempDir );
  341. if ( dwError == 0 ) {
  342. Idwlog(TEXT("GetImageHlpDllInfo - ERROR GetTempPath gle = %ld.\n"), GetLastError () );
  343. }
  344. // Uncompress it, and point to that location.
  345. //
  346. _stprintf ( szTempDirFile, TEXT("%s\\ntoskrnl.exe"), szTempDir);
  347. dwError = SetupDecompressOrCopyFile ( szCurDir, szTempDirFile, NULL );
  348. if ( dwError != ERROR_SUCCESS ) {
  349. Idwlog(TEXT("GetImageHlpDllInfo - ERROR SetupDecompressOrCopyFile gle = %ld.\n"), GetLastError () );
  350. }
  351. // Pass the location of the file.
  352. //
  353. _stprintf (szFullPath, TEXT("%s\\ntoskrnl.exe"),szTempDir );
  354. ****/
  355. Idwlog(TEXT("GetImageHlpDllInfo - szFullPath(1) = %s.\n"), szFullPath );
  356. break;
  357. case F_SYSTEM_IMAGEHLP_DLL:
  358. // Get the local systems location for the image file
  359. GetSystemDirectory( szCurDir, MAX_PATH );
  360. _stprintf (szFullPath, TEXT("%s\\imagehlp.dll"),szCurDir);
  361. Idwlog(TEXT("GetImageHlpDllInfo - szFullPath(2) = %s.\n"), szFullPath );
  362. break;
  363. }
  364. // end of new code.
  365. //
  366. }
  367. else {
  368. // This is the old standard code.
  369. //
  370. if (iFlag == F_INSTALLING_IMAGEHLP_DLL && (g_InstallData.iStageSequence == 3 || g_InstallData.iStageSequence == 2)) {
  371. iFlag = F_SYSTEM_IMAGEHLP_DLL;
  372. }
  373. switch (iFlag){
  374. case F_INSTALLING_IMAGEHLP_DLL:
  375. // Get the image data for the build that we are installing.
  376. p = _tcsstr (GetCommandLine(), TEXT("Path="));
  377. if ( p == NULL ) {
  378. Idwlog ( TEXT ( "GetImageHlpDllInfo ERROR - Could not determine path from command line, you need a Path=<path to the installing build> with trailing slash.\n") );
  379. return(FALSE);
  380. }
  381. p += _tcsclen ( TEXT ("Path=" ) );
  382. _stprintf (szCurDir, TEXT("%s"),p);
  383. Idwlog(TEXT("GetImageHlpDllInfo - Getting Installing file location as %s.\n"), szCurDir);
  384. break;
  385. case F_SYSTEM_IMAGEHLP_DLL:
  386. // Get the local systems location for the image file
  387. GetSystemDirectory( szCurDir, MAX_PATH );
  388. Idwlog(TEXT("GetImageHlpDllInfo - Getting Build, Delta, Build lab for local system.\n"));
  389. break;
  390. }
  391. _stprintf (szFullPath, TEXT("%s\\imagehlp.dll"),szCurDir);
  392. Idwlog(TEXT("GetImageHlpDllInfo - szFullPath(3) = %s.\n"), szFullPath );
  393. }
  394. Idwlog(TEXT("GetImageHlpDllInfo - Will look in [%s] for build information.\n"),szFullPath);
  395. /*******
  396. // On a network share the Imagehlp.dll is one up from where
  397. // idwlog.exe -1 is located.
  398. // On a CD its located in the same directory as where the
  399. // idwlog.exe -1 is located. We will look in both places.
  400. hFind = FindFirstFile (szFullPath, &fd);
  401. if (INVALID_HANDLE_VALUE == hFind){
  402. //
  403. // Now we know the file in not in the
  404. // immediate directory. Move up one by
  405. // culling off one more directory.
  406. ptstr = _tcsrchr(szCurDir,TEXT('\\'));
  407. if (NULL == ptstr) {
  408. Idwlog(TEXT("GetBuildInfoFromOSAndBldFile could find the file to get bld info from.\n"));
  409. return FALSE;
  410. }
  411. *ptstr = TEXT('\0');
  412. _stprintf (szFullPath, TEXT("%s\\imagehlp.dll"),szCurDir);
  413. Idwlog(TEXT("First look for imagehlp.dll in %s.\n"),szFullPath);
  414. hFind = FindFirstFile (szFullPath,&fd);
  415. if (INVALID_HANDLE_VALUE == hFind){
  416. // In case we cannot find it we will exit.
  417. // Set the currentBuild number to 0;
  418. //_tcscpy (id.szCurrentBuild, TEXT("latest"));
  419. Idwlog(TEXT("Could not find the imagehlp.dll file in %s.\n"),szFullPath);
  420. Idwlog(TEXT("Cannot get build number of the installing build.\n"));
  421. return FALSE;
  422. }
  423. }
  424. ************/
  425. Idwlog ( TEXT ( ">>>>> MyGetFileVersionInfo path = %s\n"), szFullPath );
  426. if (FALSE == MyGetFileVersionInfo(szFullPath,&lpData)){
  427. if(lpData) {
  428. free(lpData);
  429. }
  430. Idwlog(TEXT("ERROR - GetFileVersionInfo failed to retrieve Version Info from: %s.\n"), szFullPath );
  431. return FALSE;
  432. }
  433. else {
  434. Idwlog ( TEXT ( "MyGetFileVersionInfo call OK.\n") );
  435. }
  436. /*****
  437. Idwlog ( TEXT ( ">>>>> GetFileVersionInfoSize path = %s\n"), szFullPath );
  438. uLen = GetFileVersionInfoSize ( szFullPath, &dwHandle );
  439. if ( uLen == 0 ) {
  440. Idwlog ( TEXT ( "GetFileVersionInfoSize ERROR, gle = %ld\n"), GetLastError() );
  441. return FALSE;
  442. }
  443. else {
  444. Idwlog ( TEXT ( "GetFileVersionInfoSize call OK returned uLen = %ld.\n"), uLen );
  445. }
  446. b = GetFileVersionInfo ( szFullPath,
  447. dwHandle,
  448. uLen,
  449. &lpData );
  450. if ( b == 0 ) {
  451. Idwlog ( TEXT ( "GetFileVersionInfo ERROR, gle = %ld\n"), GetLastError() );
  452. return FALSE;
  453. }
  454. else {
  455. Idwlog ( TEXT ( "GetFileVersionInfo call OK.\n") );
  456. }
  457. *****/
  458. b = VerQueryValue(lpData,
  459. TEXT("\\VarFileInfo\\Translation"),
  460. (LPVOID*)&pdwTranslation,
  461. &uLen);
  462. if( b == 0 ){
  463. Idwlog ( TEXT("VerQueryValue ERROR (name does not exist or the specified resource is not valid) \\VarFileInfo\\Translation, assuming default language as: %08lx\n"), dwDefLang);
  464. pdwTranslation = &dwDefLang;
  465. }
  466. else {
  467. Idwlog ( TEXT("VerQueryValue call OK. The specified version-information structure exists, and version information is available.\n" ));
  468. if ( uLen == 0 ) {
  469. Idwlog ( TEXT("However, no value is available...\n") );
  470. }
  471. else {
  472. Idwlog ( TEXT("A value is available, it's size is: %ld.\n"), uLen );
  473. }
  474. }
  475. _stprintf(key, TEXT("\\StringFileInfo\\%04x%04x\\%s"),
  476. LOWORD(*pdwTranslation),
  477. HIWORD(*pdwTranslation),
  478. TEXT("FileVersion"));
  479. Idwlog ( TEXT ( "Just before 2nd VerQueryValue -- key = >>>%s<<< >>%x<<\n"), key, *pdwTranslation );
  480. b = VerQueryValue(lpData, key, &lpInfo, &cch);
  481. if( b ){
  482. Idwlog(TEXT("Retrieved string: >>>%s<<<\n"), lpInfo );
  483. // The output of this should be something like
  484. // 5.0.2195. 30 (LAB01_N.000215-2216)
  485. // we want the Lab part.
  486. //
  487. if (NULL == _tcsstr((LPTSTR)lpInfo,TEXT("(") )){
  488. _stprintf(szBuildLocation,
  489. TEXT("%s"),
  490. TEXT("No_Build_Lab_Information"));
  491. }else{
  492. ptstr = _tcsstr((LPTSTR)lpInfo,TEXT("(") );
  493. ptstr++;
  494. _stprintf(szBuildLocation,TEXT("%s"),ptstr);
  495. // remove the trailing ")"
  496. //
  497. szBuildLocation[_tcslen(szBuildLocation) -1 ] = 0;
  498. }
  499. }else{
  500. DWORD i;
  501. TCHAR * p = (TCHAR*)lpData;
  502. TCHAR szNewString[2048];
  503. DWORD dwAmount;
  504. DWORD dwR;
  505. Idwlog ( TEXT("VerQueryValue ERROR (name does not exist or the specified resource is not valid), gle = %ld\n"), GetLastError());
  506. _stprintf(szBuildLocation,
  507. TEXT("%s"),
  508. TEXT("No_Build_Lab_Information"));
  509. Idwlog(TEXT("Warning - Failed to get the build location in VerQueryValue.\n"));
  510. Idwlog(TEXT("Will manually try to find the data...\n"));
  511. // Let's try to find the data ourselves. We *must* do this on Win9x since Win9x doesn't know what
  512. // to do with Unicode.
  513. //
  514. // We will be careful to stay away from end of the buffer. This should be cleaned up where the 26 values are
  515. // with strlen.
  516. //
  517. for ( i = 0; i < (gdwLength - 26); i++, p++ ) {
  518. //Idwlog ( TEXT("i = %ld, p = %s\n"), i, p );
  519. //Idwlog ( TEXT ( "i = %ld, %x %c" ), i, *p, *p );
  520. if ( *p == 'F' &&
  521. *(p+2) == 'i' &&
  522. *(p+4) == 'l' &&
  523. *(p+6) == 'e' &&
  524. *(p+8) == 'V' &&
  525. *(p+10) == 'e' &&
  526. *(p+12) == 'r' &&
  527. *(p+14) == 's'
  528. ) {
  529. Idwlog(TEXT(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>We found FileVersion data by2...\n"));
  530. p += 26; // to get past word "fileversion"
  531. break;
  532. }
  533. /***
  534. if ( _tcsstr ( p, TEXT("FileVersion")) ){
  535. Idwlog(TEXT("We found FileVersion data...\n"));
  536. break;
  537. }
  538. //Idwlog ( TEXT ( "i = %ld, %x %c" ), i, *p, *p );
  539. ***/
  540. }
  541. Idwlog ( TEXT ( "p = %s\n"), p );
  542. Idwlog ( TEXT ( "%x %c" ), i, *p, *p );
  543. Idwlog ( TEXT ( "%x %c" ), i, *(p+1), *(p+1) );
  544. Idwlog ( TEXT ( "%x %c" ), i, *(p+2), *(p+2) );
  545. dwR = WideCharToMultiByte ( CP_ACP,
  546. WC_NO_BEST_FIT_CHARS,
  547. (const unsigned short *)p,
  548. -1,
  549. szNewString,
  550. 2048,
  551. NULL,
  552. NULL );
  553. if ( !dwR ) {
  554. Idwlog ( TEXT("ERROR WideChartoMultiByte: dwR = %ld, gle = %ld\n"), dwR, GetLastError () );
  555. }
  556. else {
  557. Idwlog ( TEXT("amount converted dwR = %ld, %s\n"), dwR, p = szNewString );
  558. }
  559. Idwlog(TEXT("Will print out data manually: %s\n"), p );
  560. // The output of this should be something like
  561. // 5.0.2195. 30 (LAB01_N.000215-2216)
  562. // we want the Lab part.
  563. //
  564. if (NULL == _tcsstr((LPTSTR)p,TEXT("(") )){
  565. _stprintf(szBuildLocation,
  566. TEXT("%s"),
  567. TEXT("No_Build_Lab_Information"));
  568. Idwlog ( TEXT ( "Build lab ERROR - we could not find the build # and lab, even manually.\n") );
  569. }else{
  570. ptstr = _tcsstr((LPTSTR)p,TEXT("(") );
  571. ptstr++;
  572. _stprintf(szBuildLocation,TEXT("%s"),ptstr);
  573. // remove the trailing ")"
  574. //
  575. szBuildLocation[_tcslen(szBuildLocation) -1 ] = 0;
  576. Idwlog ( TEXT ( "Build lab found: %s.\n"), szBuildLocation );
  577. }
  578. }
  579. /*********
  580. if(VerQueryValue(lpData, key, &lpInfo, &cch)){
  581. // The output of this should be something like
  582. // 5.0.2195. 30 (LAB01_N.000215-2216)
  583. // we want the Lab part.
  584. //
  585. if (NULL == _tcsstr((LPTSTR)lpInfo,TEXT("(") )){
  586. _stprintf(szBuildLocation,
  587. TEXT("%s"),
  588. TEXT("No_Build_Lab_Information"));
  589. }else{
  590. ptstr = _tcsstr((LPTSTR)lpInfo,TEXT("(") );
  591. ptstr++;
  592. _stprintf(szBuildLocation,TEXT("%s"),ptstr);
  593. // remove the trailing ")"
  594. szBuildLocation[_tcslen(szBuildLocation) -1 ] = 0;
  595. }
  596. }else{
  597. _stprintf(szBuildLocation,
  598. TEXT("%s"),
  599. TEXT("No_Build_Lab_Information"));
  600. Idwlog(TEXT("ERROR - Failed to get the build location in VerQueryValue.\n"));
  601. }
  602. **************/
  603. // This should retrieve the Major/Minor Version and build and build deltas
  604. //
  605. if (0 == VerQueryValue(lpData, "\\", (PVOID*) &pv, (UINT*) &dwTemp)) {
  606. // We have a problem.
  607. //_tcscpy (szBld, TEXT("latest"));
  608. //
  609. Idwlog(TEXT("ERROR VerQueryValue failed to retrieve Version Info from: %s\n"), szFullPath );
  610. if(lpData)
  611. free (lpData);
  612. return FALSE;
  613. }
  614. Idwlog(TEXT("GetImageHlpDllInfo - pv->dwSignature = %x\n"), pv->dwSignature );
  615. Idwlog(TEXT("GetImageHlpDllInfo - pv->dwFileVersionMS = %x\n"), pv->dwFileVersionMS );
  616. Idwlog(TEXT("GetImageHlpDllInfo - pv->dwFileVersionLS = %x\n"), pv->dwFileVersionLS );
  617. // Cast the pvoid into the correct memory arrangement
  618. //
  619. switch (iFlag){
  620. case F_INSTALLING_IMAGEHLP_DLL:
  621. Idwlog(TEXT("GetImageHlpDllInfo F_INSTALLING_IMAGEHLP_DLL - Inserting into struct Build, Delta, Build lab for the installing files.\n"));
  622. // Build Location
  623. _tcscpy( pId->szInstallingBuildSourceLocation,szBuildLocation);
  624. // Major version X.51
  625. pId->dwInstallingMajorVersion = HIWORD(pv->dwFileVersionMS);
  626. // Minor version 5.XX
  627. pId->dwInstallingMinorVersion = LOWORD(pv->dwFileVersionMS);
  628. // Build
  629. pId->dwInstallingBuild = HIWORD(pv->dwFileVersionLS);
  630. // Build Delta.
  631. pId->dwInstallingBuildDelta = LOWORD(pv->dwFileVersionLS);
  632. pId->dwInstallingSPBuild = LOWORD(pv->dwFileVersionLS);
  633. Idwlog(TEXT("GetImageHlpDllInfo F_INSTALLING_IMAGEHLP_DLL - Build = %ld, Major = %ld, Minor = %ld, Delta = %ld\n"),
  634. pId->dwInstallingBuild,
  635. pId->dwInstallingMajorVersion,
  636. pId->dwInstallingMinorVersion,
  637. pId->dwInstallingBuildDelta
  638. );
  639. break;
  640. case F_SYSTEM_IMAGEHLP_DLL:
  641. // Get the local systems location of the imagehlp.dll
  642. Idwlog(TEXT("GetImageHlpDllInfo F_SYSTEM_IMAGEHLP_DLL - Inserting into struct Build, Delta, Build lab for the local system.\n"));
  643. // Build Location
  644. _tcscpy( pId->szSystemBuildSourceLocation,szBuildLocation);
  645. // Major version X.51
  646. pId->dwSystemMajorVersion = HIWORD(pv->dwFileVersionMS);
  647. // Minor version 5.XX
  648. pId->dwSystemMinorVersion = LOWORD(pv->dwFileVersionMS);
  649. // Build
  650. pId->dwSystemBuild = HIWORD(pv->dwFileVersionLS);
  651. // Build Delta.
  652. pId->dwSystemBuildDelta = LOWORD(pv->dwFileVersionLS);
  653. pId->dwSystemSPBuild = LOWORD(pv->dwFileVersionLS);
  654. Idwlog(TEXT("GetImageHlpDllInfo F_SYSTEM_IMAGEHLP_DLL - Build = %ld, Major = %ld, Minor = %ld, Delta = %ld\n"),
  655. pId->dwSystemBuild,
  656. pId->dwSystemMajorVersion,
  657. pId->dwSystemMinorVersion,
  658. pId->dwSystemBuildDelta
  659. );
  660. break;
  661. }
  662. // The MyGetFileVersion allocates its own memory.
  663. if(lpData)
  664. free (lpData);
  665. return TRUE;
  666. }
  667. typedef struct tagVERHEAD {
  668. WORD wTotLen;
  669. WORD wValLen;
  670. WORD wType; /* always 0 */
  671. WCHAR szKey[(sizeof("VS_VERSION_INFO")+3)&~03];
  672. VS_FIXEDFILEINFO vsf;
  673. } VERHEAD ;
  674. /*
  675. Used from Filever.c wallyho. For some reason regular calls fail easier to just reuse this code
  676. * [alanau]
  677. *
  678. * MyGetFileVersionInfo: Maps a file directly without using LoadLibrary. This ensures
  679. * that the right version of the file is examined without regard to where the loaded image
  680. * is. Since this is a local function, it allocates the memory which is freed by the caller.
  681. * This makes it slightly more efficient than a GetFileVersionInfoSize/GetFileVersionInfo pair.
  682. */
  683. BOOL
  684. MyGetFileVersionInfo(LPTSTR lpszFilename, LPVOID *lpVersionInfo)
  685. {
  686. VS_FIXEDFILEINFO *pvsFFI = NULL;
  687. UINT uiBytes = 0;
  688. HINSTANCE hinst;
  689. HRSRC hVerRes;
  690. HANDLE FileHandle = NULL;
  691. HANDLE MappingHandle = NULL;
  692. LPVOID DllBase = NULL;
  693. VERHEAD *pVerHead;
  694. BOOL bResult = FALSE;
  695. DWORD dwHandle;
  696. DWORD dwLength;
  697. Idwlog ( TEXT ( "Entering MyGetFileVersionInfo.\n") );
  698. if (!lpVersionInfo) {
  699. Idwlog ( TEXT ( "MyGetFileVersionInfo: ERROR lpVersionInfo not.\n") );
  700. return FALSE;
  701. }
  702. *lpVersionInfo = NULL;
  703. FileHandle = CreateFile( lpszFilename,
  704. GENERIC_READ,
  705. FILE_SHARE_READ,
  706. NULL,
  707. OPEN_EXISTING,
  708. 0,
  709. NULL
  710. );
  711. if (FileHandle == INVALID_HANDLE_VALUE) {
  712. Idwlog ( TEXT ( "MyGetFileVersionInfo: ERROR INVALID_HANDLE.\n") );
  713. goto Cleanup;
  714. }
  715. MappingHandle = CreateFileMapping( FileHandle,
  716. NULL,
  717. PAGE_READONLY,
  718. 0,
  719. 0,
  720. NULL
  721. );
  722. if (MappingHandle == NULL) {
  723. Idwlog ( TEXT ( "MyGetFileVersionInfo: ERROR MappingHandle == NULL.\n") );
  724. goto Cleanup;
  725. }
  726. DllBase = MapViewOfFileEx( MappingHandle,
  727. FILE_MAP_READ,
  728. 0,
  729. 0,
  730. 0,
  731. NULL
  732. );
  733. if (DllBase == NULL) {
  734. Idwlog ( TEXT ( "MyGetFileVersionInfo: ERROR DllBase == NULL.\n") );
  735. goto Cleanup;
  736. }
  737. hinst = (HMODULE)((ULONG_PTR)DllBase | 0x00000001);
  738. __try {
  739. hVerRes = FindResource(hinst, MAKEINTRESOURCE(VS_VERSION_INFO), VS_FILE_INFO);
  740. if (hVerRes == NULL)
  741. {
  742. // Probably a 16-bit file. Fall back to system APIs.
  743. if(!(dwLength = GetFileVersionInfoSize(lpszFilename, &dwHandle)))
  744. {
  745. if(!GetLastError()) {
  746. Idwlog ( TEXT ( "MyGetFileVersionInfo: ERROR resource not found.\n") );
  747. SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
  748. }
  749. __leave;
  750. }
  751. if(!(*lpVersionInfo = malloc( dwLength) ) ) {
  752. Idwlog ( TEXT ( "MyGetFileVersionInfo: ERROR could not malloc.\n") );
  753. __leave;
  754. }
  755. else {
  756. Idwlog ( TEXT ( "MyGetFileVersionInfo: malloc size was: %ld.\n"), gdwLength = dwLength );
  757. }
  758. if(!GetFileVersionInfo(lpszFilename, 0, dwLength, *lpVersionInfo)) {
  759. Idwlog ( TEXT ( "MyGetFileVersionInfo: ERROR GetFileVersionInfo failed.\n") );
  760. __leave;
  761. }
  762. bResult = TRUE;
  763. Idwlog ( TEXT ( "MyGetFileVersionInfo: result is true.\n") );
  764. __leave;
  765. }
  766. pVerHead = (VERHEAD*)LoadResource(hinst, hVerRes);
  767. if (pVerHead == NULL) {
  768. Idwlog ( TEXT ( "MyGetFileVersionInfo: ERROR pVerHead == NULL.\n") );
  769. __leave;
  770. }
  771. *lpVersionInfo = malloc(pVerHead->wTotLen + pVerHead->wTotLen/2);
  772. if (*lpVersionInfo == NULL) {
  773. Idwlog ( TEXT ( "MyGetFileVersionInfo: ERROR *lpVersionInfo == NULL.\n") );
  774. __leave;
  775. }
  776. memcpy(*lpVersionInfo, (PVOID)pVerHead, gdwLength = pVerHead->wTotLen);
  777. bResult = TRUE;
  778. Idwlog ( TEXT ( "MyGetFileVersionInfo: bResult == TRUE.\n") );
  779. } __except (EXCEPTION_EXECUTE_HANDLER) {
  780. Idwlog(TEXT("MyGetFileVersionIfno ERROR - Memory problems failed to retrieve version Info from image file of the installing build.\n"));
  781. }
  782. Cleanup:
  783. if (FileHandle)
  784. CloseHandle(FileHandle);
  785. if (MappingHandle)
  786. CloseHandle(MappingHandle);
  787. if (DllBase)
  788. UnmapViewOfFile(DllBase);
  789. if (*lpVersionInfo && bResult == FALSE)
  790. free(*lpVersionInfo);
  791. Idwlog ( TEXT ( "Exiting MyGetFileVersionInfo: bResult = %ld.\n"), bResult );
  792. return bResult;
  793. }
  794. BOOL
  795. GetSkuFromDosNetInf (IN OUT LPINSTALL_DATA pId)
  796. /*++
  797. Routine Description:
  798. This will retrieve the values from Miscellaneous that tell us
  799. if the build is a personal, enterprise, etc...
  800. This will then load the value into the pId field of dwSku.
  801. Arguments:
  802. A install_data struct which contains all the recording variables necessary.
  803. Return Value:
  804. TRUE if success
  805. FALSE if fail
  806. --*/
  807. {
  808. WIN32_FIND_DATA fd;
  809. HANDLE hFind;
  810. TCHAR szFullPath [ MAX_PATH ];
  811. TCHAR szCurDir [ MAX_PATH ];//
  812. LPTSTR ptstr;
  813. // OSVERSIONINFO osex;
  814. DWORD dwLength = MAX_PATH;
  815. // DWORD dwBuild;
  816. // DWORD dwBuildDelta;
  817. TCHAR szSku[5] = "ERR";
  818. // DWORD dwDontCare;
  819. TCHAR * p = NULL;
  820. TCHAR szTmp[MAX_PATH];
  821. ptstr = szTmp;
  822. // Get the installing files location of the dosnet.inf file
  823. /****
  824. szCurDir[0] = TEXT('\0');
  825. GetModuleFileName( NULL,szCurDir, dwLength);
  826. // Remove the Idwlog.exe part and get only the directory structure.
  827. ptstr = szCurDir + _tcsclen(szCurDir);
  828. while (*ptstr-- != TEXT('\\'));
  829. ptstr++;
  830. *ptstr = TEXT('\0');
  831. Idwlog(TEXT("Getting DosNet.inf file location as %s.\n"), szCurDir);
  832. ****/
  833. p = _tcsstr (GetCommandLine(), TEXT("Path="));
  834. if ( p == NULL ) {
  835. Idwlog ( TEXT ( "GetSkuFromDosNetInf ERROR - Could not determine path from command line, you need a Path=<path to the installing build> with trailing slash.\n") );
  836. pId->dwSku = 666;
  837. return(FALSE);
  838. }
  839. p += _tcsclen ( TEXT ("Path=" ) );
  840. Idwlog(TEXT("Source path = %s\n"), p );
  841. // Use this to get the location
  842. // idwlog.exe -1 is run from. This tool
  843. // will always assume the dosnet.inf is in its
  844. // current path or two up.
  845. _stprintf (szFullPath, TEXT("%s\\dosnet.inf"),p);
  846. Idwlog(TEXT("Will attempt to open to get ProductType in szFullPath = %s.\n"), szFullPath);
  847. GetPrivateProfileString(TEXT("Miscellaneous"),
  848. TEXT("ProductType"),
  849. TEXT("0"),
  850. szSku,
  851. sizeof(szSku)/sizeof(TCHAR),
  852. szFullPath);
  853. // Check to see if there was an error in the above call getting the value.
  854. // If so, default to Professional for the value, but return.
  855. //
  856. if ( _tcsstr (szSku, TEXT("ERR")) ) {
  857. pId->dwSku = 0;
  858. Idwlog ( TEXT ( "ERROR - GetSkuFromDosNetInf GetPrivateProfileString FAILed. Will return pid->dwSku = %d\n"), pId->dwSku );
  859. return(FALSE);
  860. }
  861. /*
  862. case 0: // Professional
  863. case 1: // Server
  864. case 2: // Advanced Server
  865. case 3: // DataCenter
  866. case 4: // Personal
  867. case 5: // Blade Server
  868. case 6: // Small Business Server
  869. default: // Professional
  870. */
  871. *ptstr = TEXT('\0');
  872. pId->dwSku = _tcstoul(szSku, &ptstr, 10);
  873. if(pId->dwSku > 6){
  874. // default to Professional
  875. Idwlog ( TEXT ( "ERROR - found an unknown ProductType in dosnet.inf pid->dwSku = %d\n"), pId->dwSku );
  876. pId->dwSku = 0;
  877. return(FALSE);
  878. }
  879. Idwlog ( TEXT ( "We found the following product type: %d\n"), pId->dwSku );
  880. return TRUE;
  881. }