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.

960 lines
30 KiB

  1. /*
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. appcompat.c
  5. Abstract:
  6. An application to launch a required APP with the
  7. version and the APPCOMPAT flags set.
  8. */
  9. /* INCLUDES */
  10. #define UNICODE 1
  11. #include <windows.h>
  12. #include <commdlg.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <stdio.h>
  17. #include <shellapi.h>
  18. #include <tchar.h>
  19. #include <htmlhelp.h>
  20. #include <apcompat.h>
  21. #include "appcompat.h"
  22. #define MAXRES 256
  23. #define MAXKEY 100
  24. #define MAXDATA 10
  25. #define MAXTITLE 100
  26. INT_PTR CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
  27. int MakeAppCompatGoo(TCHAR*, LARGE_INTEGER*, UINT);
  28. long DeleteSpecificVal(HKEY );
  29. extern TCHAR* CheckExtension(TCHAR*);
  30. /* Global */
  31. // Pattern string.. MajorVersion, MinorVersion, BuildNumber,ServicePackMajor, ServicePackMinor,
  32. // PlatformID, CSDVersion string....
  33. const TCHAR* pVersionVal[] = {
  34. TEXT("4,0,1381,3,0,2,Service Pack 3"),
  35. TEXT("4,0,1381,4,0,2,Service Pack 4"),
  36. TEXT("4,0,1381,5,0,2,Service Pack 5"),
  37. TEXT("4,10,1998,0,0,1,"),
  38. TEXT("4,0,950,0,0,1,"),
  39. NULL
  40. };
  41. #define MAXVERNUM ( sizeof(pVersionVal)/sizeof(TCHAR*) ) - 1
  42. const TCHAR szFilter[] = TEXT("EXE Files (*.EXE)\0*.exe\0") \
  43. TEXT("All Files (*.*)\0*.*\0\0");
  44. HINSTANCE g_hInstance;
  45. extern PVOID g_lpPrevRegSettings;
  46. BOOL g_fAppCompatGoo = FALSE;
  47. BOOLEAN g_fNotPermanent = FALSE;
  48. extern BOOLEAN g_GooAppendFlag;
  49. // Converts Text to interger.
  50. int TextToInt(
  51. const TCHAR *nptr
  52. )
  53. {
  54. int c; /* current char */
  55. int total; /* current total */
  56. int sign; /* if '-', then negative, otherwise positive */
  57. /* skip whitespace */
  58. while ( *nptr == TEXT(' ') )
  59. ++nptr;
  60. c = (int)*nptr++;
  61. sign = c; /* save sign indication */
  62. if (c == TEXT('-') || c == TEXT('+') )
  63. c = (int)*nptr++; /* skip sign */
  64. total = 0;
  65. while ( (c>=TEXT('0')) && (c <= TEXT('9')) ) {
  66. total = 10 * total + (c - TEXT('0') ); /* accumulate digit */
  67. c = (int)*nptr++; /* get next char */
  68. }
  69. if (sign == '-')
  70. return -total;
  71. else
  72. return total; /* return result, negated if necessary */
  73. }
  74. TCHAR* CheckExtension(TCHAR* szTitle)
  75. {
  76. TCHAR *pCh;
  77. pCh = szTitle;
  78. while(*pCh != TEXT('.'))
  79. {
  80. if(*pCh == TEXT('\0'))
  81. break;
  82. pCh++;
  83. }
  84. if(*pCh == TEXT('\0'))
  85. return NULL;
  86. else
  87. {
  88. pCh++;
  89. return pCh;
  90. }
  91. }
  92. VOID GetTitleAndCommandLine(TCHAR* pEditBuf, TCHAR* pszTitle, TCHAR* pszCommandLine)
  93. {
  94. TCHAR szTitleAndCommandLine[_MAX_PATH];
  95. TCHAR* pszTemp, *pszTmpTitle;
  96. UINT i = 0;
  97. lstrcpy(szTitleAndCommandLine, pEditBuf);
  98. pszTmpTitle = pszTemp = szTitleAndCommandLine;
  99. if(*pszTemp == TEXT('\"') ){ // The title has quotes(" "). It has command line params.
  100. pszTemp++;
  101. while(*pszTemp != TEXT('\"') ){
  102. pszTemp++;
  103. if(*pszTemp == TEXT('\0') )
  104. break;
  105. if(*pszTemp == TEXT('\\') )
  106. pszTmpTitle = pszTemp + 1;
  107. }
  108. }
  109. else{ // No quotes(" ")...This means that there are no command line parameters.
  110. GetFileTitle(pEditBuf,pszTitle,MAX_PATH);
  111. pszCommandLine = NULL;
  112. return;
  113. }
  114. RtlZeroMemory(pszCommandLine, MAX_PATH);
  115. if(*pszTemp != TEXT('\0') ){ // There are command line paramaters for the APP.
  116. *(pszTemp ) = TEXT('\0');
  117. lstrcpy(pEditBuf, szTitleAndCommandLine);
  118. // For Paths beginning with a '"' and ending with a '"'.
  119. if(*pEditBuf == TEXT('\"') )
  120. lstrcat(pEditBuf, TEXT("\"") );
  121. // Now copy over the Command line parameters.
  122. pszTemp++;
  123. while( (*pszTemp) != TEXT('\0') ){
  124. *(pszCommandLine + i) = *pszTemp;
  125. i++;
  126. pszTemp++;
  127. }
  128. *(pszCommandLine + i) = TEXT('\0');
  129. }
  130. lstrcpy(pszTitle, pszTmpTitle);
  131. }
  132. VOID GetFileExtension(TCHAR* pEditBuf, TCHAR* pszTitle,TCHAR* pszCommandLine)
  133. {
  134. GetTitleAndCommandLine(pEditBuf, pszTitle, pszCommandLine);
  135. if(CheckExtension(pszTitle) == NULL)
  136. lstrcat(pszTitle,TEXT(".exe"));
  137. }
  138. TCHAR* GetNextWord(BOOLEAN* pfEndOfLine,TCHAR* pStr)
  139. {
  140. TCHAR* pCh;
  141. pCh = pStr;
  142. //Skip white spaces..
  143. while((*pCh == TEXT(' ')) || (*pCh == TEXT('\t')))
  144. pCh++;
  145. // Fix for Command line parameters (from the command line within " " :)) ).
  146. if( *pCh == TEXT('\"') ){
  147. pCh++;
  148. while( *pCh != TEXT('\0') ) // Scan till the end when the string starts with a '"'.
  149. pCh++;
  150. *pfEndOfLine = TRUE;
  151. return pCh;
  152. }
  153. // End ..Fix for Command line parameters (from the command line within " " :)) ).
  154. while( ((*pCh)!=TEXT('-')) && ((*pCh)!=TEXT('\0')) )
  155. {
  156. pCh++;
  157. }
  158. if((*pCh) == TEXT('\0'))
  159. *pfEndOfLine = TRUE;
  160. else
  161. *pfEndOfLine = FALSE;
  162. return pCh;
  163. }
  164. void SkipBlanks(TCHAR* pStr)
  165. {
  166. TCHAR* pTemp;
  167. if(*(pStr - 1) == TEXT(' '))
  168. {
  169. pTemp = pStr;
  170. while(*(pTemp - 1) == TEXT(' '))
  171. pTemp--;
  172. *pTemp = TEXT('\0');
  173. }
  174. }
  175. VOID SetRegistryVal(TCHAR* szTitle, TCHAR* szVal,PTCHAR szBuffer,DWORD dwType)
  176. {
  177. long lResult;
  178. TCHAR szSubKey[MAXKEY];
  179. HKEY hKey;
  180. wsprintf(szSubKey, TEXT("software\\microsoft\\windows NT\\currentversion\\Image File Execution Options\\%s"),szTitle);
  181. lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  182. szSubKey,
  183. 0,
  184. TEXT("\0"),
  185. 0,
  186. KEY_WRITE,
  187. NULL,
  188. &hKey,
  189. NULL);
  190. if(lResult == ERROR_SUCCESS)
  191. {
  192. RegSetValueEx(hKey,szVal,
  193. 0, dwType,(CONST BYTE*)szBuffer, lstrlen(szBuffer) + 1);
  194. RegCloseKey(hKey);
  195. }
  196. }
  197. long RestoreRegistryVal(szTitle)
  198. {
  199. long lResult;
  200. TCHAR szSubKey[MAXKEY];
  201. HKEY hKey;
  202. wsprintf(szSubKey, TEXT("software\\microsoft\\windows NT\\currentversion\\Image File Execution Options\\%s"),szTitle);
  203. lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  204. szSubKey,
  205. 0,
  206. TEXT("\0"),
  207. 0,
  208. KEY_WRITE,
  209. NULL,
  210. &hKey,
  211. NULL);
  212. if(lResult == ERROR_SUCCESS)
  213. {
  214. lResult = RegSetValueEx(hKey,TEXT("ApplicationGoo"),
  215. 0, REG_BINARY,(CONST BYTE*)g_lpPrevRegSettings, *((PULONG)g_lpPrevRegSettings) );
  216. if(ERROR_SUCCESS != lResult)
  217. MessageBox(NULL,TEXT("Appending ApplicationGoo failed !!"),TEXT(""),IDOK);
  218. RegCloseKey(hKey);
  219. }
  220. return lResult;
  221. }
  222. long DeleteKey(TCHAR* szTitle, BOOL bGooKeyPresent)
  223. {
  224. long lRet;
  225. HKEY hKey;
  226. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  227. TEXT("software\\microsoft\\windows NT\\currentversion\\Image File Execution Options"),
  228. 0,
  229. KEY_WRITE,
  230. &hKey);
  231. if(ERROR_SUCCESS == lRet){
  232. if((!g_fAppCompatGoo) &&
  233. ( TRUE == bGooKeyPresent) ){ // We did not set ApplicationGoo at all. So, we cannot delete it !
  234. lRet = DeleteSpecificVal(hKey);
  235. return lRet;
  236. }
  237. RegDeleteKey(hKey, szTitle);
  238. RegCloseKey(hKey);
  239. // If there was a previous entry of ApplicationGoo in the registry.
  240. if(g_GooAppendFlag)
  241. lRet = RestoreRegistryVal(szTitle);
  242. }// If ERROR_SUCCESS
  243. return lRet;
  244. }
  245. long DeleteSpecificVal(HKEY hKey)
  246. {
  247. if(g_fNotPermanent == TRUE){
  248. if(g_fAppCompatGoo){
  249. RegDeleteValue(hKey, TEXT("ApplicationGoo") );
  250. if(g_GooAppendFlag){
  251. if( RegSetValueEx(hKey,
  252. TEXT("ApplicationGoo"),
  253. 0,
  254. REG_BINARY,
  255. (CONST BYTE*)g_lpPrevRegSettings,
  256. *((PULONG)g_lpPrevRegSettings)
  257. ) != ERROR_SUCCESS )
  258. MessageBox(NULL,TEXT("Appending ApplicationGoo failed !!"),TEXT(""),IDOK);
  259. }
  260. }
  261. }
  262. return( RegDeleteValue( hKey,TEXT("DisableHeapLookAside") ) );
  263. }
  264. long CheckAndDeleteKey(TCHAR* szTitle, BOOL Check)
  265. {
  266. long lResult,lRet = -1;
  267. TCHAR szSubKey[MAXKEY], szData[MAXDATA], szKeyName[MAXKEY],szResult[MAXDATA];
  268. int Size,KeyLength, indx =0;
  269. HKEY hKey;
  270. DWORD dwType;
  271. BOOLEAN bSpecificKey = FALSE, bGooKeyPresent = FALSE;
  272. wsprintf(szSubKey,TEXT("software\\microsoft\\windows NT\\currentversion\\Image File Execution Options\\%s"),szTitle);
  273. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  274. szSubKey,
  275. 0,
  276. KEY_SET_VALUE | KEY_QUERY_VALUE,
  277. &hKey);
  278. if(ERROR_SUCCESS == lResult){
  279. Size = sizeof(szData) + 1;
  280. lResult = RegQueryValueEx(hKey,
  281. TEXT("DisableHeapLookAside"),
  282. NULL,
  283. &dwType,
  284. (LPBYTE)szData,
  285. &Size);
  286. if(Check)
  287. return lResult;
  288. /*
  289. This is done to check whether this is the only value under this KEY.
  290. If there are other values under this key, only this value is deleted
  291. */
  292. KeyLength = sizeof(szKeyName) + 1;
  293. while(RegEnumValue(hKey,
  294. indx,
  295. szKeyName,
  296. &KeyLength,
  297. NULL,
  298. NULL,
  299. NULL,
  300. NULL) != ERROR_NO_MORE_ITEMS)
  301. {
  302. if(lstrcmpi(szKeyName,TEXT("DisableHeapLookAside"))!=0){
  303. if(lstrcmpi(szKeyName,TEXT("ApplicationGoo"))!=0 ||
  304. g_fNotPermanent == FALSE){ // ApplicationGoo is present but it should be permanent...
  305. bSpecificKey = TRUE;
  306. lRet = DeleteSpecificVal(hKey);
  307. break;
  308. }
  309. bGooKeyPresent = TRUE; // If it has come here, then it is equal to "ApplicationGoo"
  310. }
  311. indx++;
  312. KeyLength = sizeof(szKeyName) + 1;
  313. }
  314. RegCloseKey(hKey);
  315. if(!bSpecificKey){
  316. lRet = DeleteKey(szTitle, bGooKeyPresent);
  317. }
  318. }
  319. return lRet;
  320. }
  321. void DetailError(DWORD dwErrMsg)
  322. {
  323. LPVOID lpMsgBuf;
  324. if(FormatMessage(
  325. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  326. FORMAT_MESSAGE_FROM_SYSTEM |
  327. FORMAT_MESSAGE_IGNORE_INSERTS,
  328. NULL,
  329. dwErrMsg,
  330. MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
  331. (LPTSTR)&lpMsgBuf,
  332. 0,
  333. NULL
  334. ) != 0){
  335. MessageBox(NULL, lpMsgBuf, TEXT(""), IDOK);
  336. }
  337. LocalFree(lpMsgBuf);
  338. }
  339. VOID ExecuteApp(HWND hWnd, TCHAR* AppName,TCHAR* szTitle,TCHAR* pszCommandLine, BOOLEAN fMask)
  340. {
  341. SHELLEXECUTEINFO sei;
  342. MSG msg;
  343. static int cnt = 0;
  344. memset(&sei, 0, sizeof(SHELLEXECUTEINFO) );
  345. sei.cbSize = sizeof(SHELLEXECUTEINFO);
  346. sei.hwnd = hWnd;
  347. sei.lpVerb = TEXT("open");
  348. sei.lpFile = AppName;
  349. sei.nShow = SW_SHOWDEFAULT;
  350. sei.lpParameters = pszCommandLine;
  351. if(fMask){
  352. sei.fMask = SEE_MASK_NOCLOSEPROCESS;
  353. }
  354. if(ShellExecuteEx(&sei) == FALSE) { /* If the API fails */
  355. CheckAndDeleteKey(szTitle, FALSE);
  356. DetailError( GetLastError() );
  357. }
  358. else{ // Was successful in launching the application.
  359. // Wait till the process terminates...
  360. if(fMask){
  361. if(NULL != sei.hProcess ){ // The hProcess can be NULL sometimes....
  362. while(WaitForSingleObject(sei.hProcess, 5000)== WAIT_TIMEOUT){
  363. while(PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)){
  364. TranslateMessage(&msg);
  365. DispatchMessage(&msg);
  366. }
  367. cnt++;
  368. if(cnt == 15)
  369. break;
  370. }
  371. CheckAndDeleteKey(szTitle, FALSE );
  372. CloseHandle(sei.hProcess);
  373. }
  374. else
  375. MessageBox(NULL, TEXT(" Process Handle is NULL"), TEXT(""), IDOK);
  376. }
  377. }
  378. }
  379. VOID SetTempPath(VOID)
  380. {
  381. TCHAR szEnv[_MAX_PATH],szTemp[_MAX_PATH];
  382. int indx1=0,indx2 =0;
  383. GetEnvironmentVariable(TEXT("TEMP"),szTemp,_MAX_PATH);
  384. szEnv[0] = szTemp[0];
  385. lstrcpy(&szEnv[1],TEXT(":\\Temp"));
  386. if(SetEnvironmentVariable(TEXT("TEMP"), szEnv) == 0){
  387. DetailError(GetLastError());
  388. }
  389. }
  390. VOID GetDirectoryPath(LPTSTR pszModulePath,LPTSTR pszDirectoryPath)
  391. {
  392. TCHAR* pTmp, *pSwap;
  393. pTmp = (TCHAR*) malloc( sizeof(TCHAR) * (lstrlen((LPCTSTR)pszModulePath) + 1) );
  394. if(pTmp){
  395. lstrcpy(pTmp, pszModulePath);
  396. pSwap = pTmp;
  397. pTmp += lstrlen((LPCTSTR)pszModulePath);
  398. while(*pTmp != TEXT('\\') ){
  399. pTmp--;
  400. }
  401. *pTmp = TEXT('\0');
  402. pTmp = pSwap;
  403. lstrcpy(pszDirectoryPath, pTmp);
  404. free(pTmp);
  405. }
  406. }
  407. VOID GetHelpPath(LPTSTR pszPath)
  408. {
  409. TCHAR szFilePath[_MAX_PATH] = {0};
  410. GetModuleFileName(NULL,szFilePath,_MAX_PATH);
  411. GetDirectoryPath(szFilePath, pszPath);
  412. lstrcat(pszPath, TEXT("\\w2rksupp.chm") );
  413. }
  414. /* Main Entry point */
  415. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  416. LPSTR lpszCmdLine, int nCmdShow)
  417. {
  418. const static TCHAR szAppName [] = TEXT("AppCompat");
  419. MSG msg;
  420. WNDCLASS wndclass;
  421. /* Addition for Command line Parameters*/
  422. TCHAR *AppName = NULL, *pCh = NULL, *pNextWord=NULL;
  423. BOOLEAN fEnd = FALSE, fDisableHeapLookAside = FALSE, fSetTemp = FALSE,fHelpDisplay = FALSE;
  424. BOOL fKeepRegistrySetting = FALSE;
  425. UINT VersionNum = 5,indx,length;
  426. HKEY hKey;
  427. TCHAR szTitle[_MAX_PATH], szSubKey[MAXKEY],szKeyName[MAXKEY];
  428. TCHAR szCommandLine[_MAX_PATH];
  429. LPTSTR pStr;
  430. long lResult;
  431. LPTSTR lpszCommandLn;
  432. TCHAR szDirectoryPath[_MAX_PATH];
  433. HWND hHelpWnd;
  434. static LARGE_INTEGER AppCompatFlag;
  435. static TCHAR szCurDir[MAX_PATH];
  436. g_hInstance = hInstance;
  437. // For Unicode
  438. lpszCommandLn = GetCommandLine();
  439. pStr = (TCHAR*)malloc( sizeof(TCHAR) * ( lstrlen((LPCTSTR)lpszCommandLn) + 1) );
  440. if(pStr != NULL)
  441. {
  442. lstrcpy(pStr, (LPCTSTR)lpszCommandLn);
  443. pCh = pStr;
  444. }
  445. else{
  446. return 0;
  447. }
  448. // Skip till the first delimiter
  449. while(*pCh != TEXT('-') ){
  450. if(*pCh == TEXT('\0') )
  451. break;
  452. pCh++;
  453. }
  454. if(*pCh == TEXT('-') )
  455. {
  456. pCh++; /* If '-' is found, skip to the next
  457. character */
  458. if(*pCh != TEXT('\0') ){
  459. do
  460. {
  461. pCh++;
  462. pNextWord = GetNextWord(&fEnd,pCh);
  463. switch(LOWORD( CharLower((LPTSTR)*(pCh - 1))) )
  464. {
  465. case TEXT('d'):
  466. /* For Disable Heap look-aside */
  467. fDisableHeapLookAside = TRUE;
  468. break;
  469. case TEXT('k'):
  470. /* For Keep the Registry settings */
  471. fKeepRegistrySetting = TRUE;
  472. break;
  473. case TEXT('g'):
  474. /* For GetDiskFreespace in AppCompatGoo registry setting */
  475. g_fAppCompatGoo = TRUE;
  476. AppCompatFlag.LowPart |= KACF_GETDISKFREESPACE;
  477. break;
  478. #ifdef EXTRA_APP_COMPAT
  479. case TEXT('f'): // Pre-Windows 2000 Free Threading Model(FTM).
  480. g_fAppCompatGoo = TRUE;
  481. AppCompatFlag.LowPart |= KACF_FTMFROMCURRENTAPT;
  482. break;
  483. case TEXT('o'):
  484. g_fAppCompatGoo = TRUE;
  485. AppCompatFlag.LowPart |=KACF_OLDGETSHORTPATHNAME;
  486. #endif
  487. case TEXT('t'):
  488. /* For Disable Heap look-aside */
  489. fSetTemp = TRUE;
  490. g_fAppCompatGoo = TRUE;
  491. AppCompatFlag.LowPart |=KACF_GETTEMPPATH;
  492. break;
  493. case TEXT('v'):
  494. SkipBlanks(pNextWord);
  495. VersionNum = TextToInt((LPCTSTR)pCh) - 1;
  496. if(VersionNum >= MAXVERNUM) {
  497. fHelpDisplay = TRUE;
  498. GetHelpPath(szDirectoryPath);
  499. hHelpWnd = HtmlHelp(NULL, szDirectoryPath, HH_DISPLAY_TOPIC,
  500. (DWORD_PTR)IDHH_CMDSYNTAX );
  501. while(IsWindow(hHelpWnd) )
  502. Sleep(200);
  503. return 0;
  504. //break;
  505. }
  506. // Set the appcompatgoo flag .
  507. if(VersionNum <= (MAXVERNUM - 1)){
  508. g_fAppCompatGoo = TRUE;
  509. AppCompatFlag.LowPart |= KACF_VERSIONLIE;
  510. }
  511. break;
  512. case TEXT('x'): // NOTE: To pass command line parameters to the App. pass it in " " after
  513. // -x . Eg. apcompat -x"yyy.exe " ..Command line params..blah..blah..
  514. SkipBlanks(pNextWord);
  515. AppName = (TCHAR*)malloc(sizeof(TCHAR) * ( lstrlen(pCh) + 1) );
  516. if(AppName != NULL)
  517. lstrcpy(AppName,pCh);
  518. break;
  519. case TEXT('h'):
  520. default :
  521. GetHelpPath(szDirectoryPath);
  522. hHelpWnd = HtmlHelp(GetDesktopWindow(), szDirectoryPath, HH_DISPLAY_TOPIC,
  523. (DWORD_PTR)IDHH_CMDSYNTAX );
  524. // Loop till the Help window exists.
  525. while(IsWindow(hHelpWnd) )
  526. Sleep(200);
  527. if(AppName)
  528. free(AppName);
  529. return 0;
  530. } // End switch
  531. if(fEnd == FALSE)
  532. pCh = pNextWord+1;
  533. }while( FALSE == fEnd);
  534. }
  535. if((AppName == NULL) ||
  536. lstrlen(AppName) == 0)/* Return if no Application name given */
  537. {
  538. if(FALSE == fHelpDisplay ){
  539. GetHelpPath(szDirectoryPath);
  540. hHelpWnd = HtmlHelp(NULL, szDirectoryPath, HH_DISPLAY_TOPIC,
  541. (DWORD_PTR)IDHH_CMDSYNTAX );
  542. while(IsWindow(hHelpWnd) )
  543. Sleep(200);
  544. }
  545. return 0;
  546. }
  547. memset(szCommandLine, 0, MAX_PATH);
  548. GetFileExtension(AppName,szTitle,szCommandLine);
  549. GetDirectoryPath(AppName, szCurDir);
  550. SetCurrentDirectory(szCurDir);
  551. if(fDisableHeapLookAside)
  552. {
  553. SetRegistryVal(szTitle,TEXT("DisableHeapLookAside"), TEXT("1"),REG_SZ );
  554. }
  555. else{
  556. CheckAndDeleteKey(szTitle,FALSE);
  557. } //End Else
  558. if(fSetTemp){
  559. SetTempPath();
  560. }
  561. if(!fKeepRegistrySetting)
  562. g_fNotPermanent = TRUE;
  563. if(g_fAppCompatGoo)
  564. MakeAppCompatGoo(AppName,&AppCompatFlag,VersionNum);
  565. if(SetEnvironmentVariable(TEXT("_COMPAT_VER_NNN"), pVersionVal[VersionNum]) == 0)
  566. {
  567. if( ERROR_ENVVAR_NOT_FOUND != GetLastError() )
  568. DetailError( GetLastError() );
  569. }
  570. // Execute the application.
  571. if(fKeepRegistrySetting)
  572. ExecuteApp(NULL, AppName,szTitle,szCommandLine,FALSE);
  573. else{
  574. ExecuteApp(NULL, AppName,szTitle,szCommandLine,TRUE);
  575. }
  576. if(AppName)
  577. free(AppName);
  578. if(pStr)
  579. free(pStr);
  580. GlobalFree(g_lpPrevRegSettings);
  581. return 0;
  582. }
  583. /* Create a MODAL Dialog */
  584. DialogBox(hInstance, TEXT("DialogProc"),(HWND)NULL, DialogProc);
  585. while(GetMessage(&msg, NULL, 0, 0))
  586. {
  587. TranslateMessage(&msg);
  588. DispatchMessage(&msg);
  589. }
  590. return (int)msg.wParam ;
  591. }
  592. /* Dialog procedure... */
  593. INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  594. {
  595. int dCharCnt,indx,length;
  596. TCHAR EditCtrlBuf[_MAX_PATH];
  597. static int BufCnt;
  598. TCHAR FileBuf[_MAX_PATH];
  599. TCHAR FileTitle[_MAX_PATH],szCommandLine[MAX_PATH];
  600. TCHAR szDirectoryPath[_MAX_PATH];
  601. static HANDLE hEditCtrl;
  602. static HANDLE hRadioBtn;
  603. static HANDLE hBrowseBtn;
  604. static HANDLE hLaunchBtn,hCheck1,hCheck2,hCheck3,hCheck4,hDCOMFTM,hOldPathName;
  605. static const TCHAR* pEnvVal = NULL;
  606. OPENFILENAME ofn;
  607. HKEY hKey;
  608. TCHAR szTitle[MAXTITLE],szKeyName[MAXKEY],szSubKey[MAXKEY];
  609. TCHAR szFileName[_MAX_PATH];
  610. DWORD dwEnvSetError;
  611. static LARGE_INTEGER AppCompatFlag ;
  612. static UINT uOsVerID = IDD_NONE;
  613. static BOOL fOfnFlag = FALSE;
  614. static TCHAR szCurDir[MAX_PATH];
  615. switch(uMsg)
  616. {
  617. case WM_INITDIALOG:
  618. hEditCtrl = GetDlgItem(hwndDlg, IDD_APPEDIT); /* To be used when reading and
  619. writing from the EDIT control */
  620. hRadioBtn = GetDlgItem(hwndDlg, IDD_NONE);
  621. SendMessage(hRadioBtn , BM_SETCHECK, 1, 0L);
  622. SetFocus(hEditCtrl);
  623. return TRUE;
  624. case WM_CLOSE:
  625. EndDialog(hwndDlg, 0);
  626. break;
  627. case WM_DESTROY:
  628. PostQuitMessage(0);
  629. return 0;
  630. case WM_COMMAND:
  631. if(FALSE==fOfnFlag){
  632. if( LOWORD(wParam) == IDD_APPEDIT ){
  633. if( HIWORD(wParam) == EN_UPDATE){
  634. GetWindowText(hEditCtrl,EditCtrlBuf, _MAX_PATH);
  635. /* Check whether the *.exe is present in Registry */
  636. GetFileExtension(EditCtrlBuf,szTitle,szCommandLine);
  637. if(CheckAndDeleteKey(szTitle,TRUE) == ERROR_SUCCESS){
  638. /* The executable already has an entry
  639. in the registry */
  640. hCheck1 = GetDlgItem(hwndDlg, IDD_CHECK1);
  641. SendMessage(hCheck1,BM_SETCHECK, 1, 0L);
  642. }
  643. else{ // Uncheck if previously checked only.
  644. if( SendMessage(hCheck1,BM_GETCHECK, 0, 0L) )
  645. SendMessage(hCheck1,BM_SETCHECK, 0, 0L);
  646. }
  647. }
  648. }
  649. }
  650. switch(wParam)
  651. {
  652. case IDCANCEL:
  653. EndDialog(hwndDlg, 0);
  654. break;
  655. case IDD_HELP:
  656. GetHelpPath(szDirectoryPath);
  657. lstrcat(szDirectoryPath, TEXT("::/topics/appcomp.htm>mainwin") );
  658. HtmlHelp(GetDesktopWindow(), szDirectoryPath, HH_DISPLAY_TOPIC,(DWORD_PTR) NULL);
  659. break;
  660. /*
  661. For the Browse button, Open the FileOpen dialog and get the
  662. application path.
  663. Display the path in the Edit box.
  664. */
  665. case IDD_BROWSE:
  666. GetDlgItemText(hwndDlg, IDD_APPEDIT, EditCtrlBuf, _MAX_PATH);
  667. memset(&ofn, 0, sizeof(OPENFILENAME) );
  668. FileBuf[0] = TEXT('\0');
  669. /* Initialize the Ofn structure */
  670. ofn.lStructSize = sizeof (OPENFILENAME) ;
  671. ofn.hwndOwner = hwndDlg;
  672. ofn.lpstrFilter = szFilter;
  673. ofn.lpstrFile = FileBuf;
  674. ofn.nMaxFile = _MAX_PATH ;
  675. ofn.lpstrInitialDir= EditCtrlBuf;
  676. ofn.Flags = OFN_PATHMUSTEXIST |
  677. OFN_FILEMUSTEXIST;
  678. if( GetOpenFileName (&ofn) != 0){
  679. /* Got the file name ...*/
  680. // To put a '"' before and after what is typed...
  681. if( (*FileBuf) != TEXT('\"') ){
  682. memset(EditCtrlBuf, 0, MAX_PATH);
  683. *(EditCtrlBuf) = TEXT('\"');
  684. lstrcat(EditCtrlBuf, FileBuf);
  685. lstrcat(EditCtrlBuf, TEXT("\""));
  686. SetWindowText(hEditCtrl,EditCtrlBuf);
  687. }
  688. // Set the flag so that anything entered after this will not be taken over by
  689. // the Edit control input...
  690. fOfnFlag = TRUE;
  691. /* Check whether the *.exe is present in Registry */
  692. GetFileExtension(FileBuf,szTitle,szCommandLine);
  693. if(CheckAndDeleteKey(szTitle,TRUE) == ERROR_SUCCESS){
  694. /* The executable already has an entry
  695. in the registry */
  696. hCheck1 = GetDlgItem(hwndDlg, IDD_CHECK1);
  697. SendMessage(hCheck1,BM_SETCHECK, 1, 0L);
  698. }
  699. /* At this pt. set focus on the 'LAUNCH' button */
  700. hLaunchBtn = GetDlgItem(hwndDlg, IDD_LAUNCH);
  701. SetFocus(hLaunchBtn);
  702. }
  703. break;
  704. /*
  705. When any of the Radio buttons in the OS version group is checked,
  706. get the version ID and store the corresponding COMPAT flag.. in the
  707. local variable.
  708. */
  709. case IDD_WIN95:
  710. case IDD_WIN98:
  711. case IDD_WINNT43:
  712. case IDD_WINNT44:
  713. case IDD_WINNT45:
  714. case IDD_NONE:
  715. if(wParam != IDD_NONE){
  716. g_fAppCompatGoo = TRUE;
  717. AppCompatFlag.LowPart |= KACF_VERSIONLIE;
  718. }
  719. uOsVerID = (UINT)(wParam - FIRSTBUTTON);
  720. CheckRadioButton(hwndDlg,(int)FIRSTBUTTON,(int)LASTBUTTON,(int)wParam);
  721. pEnvVal = pVersionVal[wParam - FIRSTBUTTON];
  722. break;
  723. case IDD_LAUNCH:
  724. dCharCnt = GetWindowTextLength( hEditCtrl );
  725. if(dCharCnt > 0){
  726. /*
  727. Go in only if something is present in the
  728. EDIT box
  729. */
  730. if(GetWindowText(hEditCtrl, EditCtrlBuf, dCharCnt + 1) == 0){
  731. DetailError(GetLastError() );
  732. }
  733. else{ /* Launch the APP using ShellExecuteEx */
  734. memset(szCommandLine, 0, MAX_PATH);
  735. GetFileExtension(EditCtrlBuf,szTitle,szCommandLine);
  736. GetDirectoryPath(EditCtrlBuf, szCurDir);
  737. SetCurrentDirectory(szCurDir);
  738. hCheck1 = GetDlgItem(hwndDlg, IDD_CHECK1);
  739. if( SendMessage(hCheck1, BM_GETSTATE, 0, 0L)){
  740. /* The checkbox has been checked
  741. - DisableHeapLookAside */
  742. SetRegistryVal(szTitle, TEXT("DisableHeapLookAside"), TEXT("1"),REG_SZ );
  743. }
  744. else{
  745. // If it is not thru the BROWSE button...user has got
  746. // here by typing the path in the Edit Ctrl...
  747. CheckAndDeleteKey(szTitle,FALSE);
  748. }
  749. hCheck2 = GetDlgItem(hwndDlg, IDD_CHECK2);
  750. if( SendMessage(hCheck2, BM_GETSTATE, 0, 0L)){
  751. // Short Temp path.
  752. g_fAppCompatGoo = TRUE;
  753. AppCompatFlag.LowPart |=KACF_GETTEMPPATH;
  754. SetTempPath();
  755. }
  756. hCheck4 = GetDlgItem(hwndDlg, IDD_CHECK4);
  757. if( SendMessage(hCheck4, BM_GETSTATE, 0, 0L) ){
  758. g_fAppCompatGoo = TRUE;
  759. AppCompatFlag.LowPart |= KACF_GETDISKFREESPACE;
  760. }
  761. #ifdef EXTRA_APP_COMPAT
  762. hDCOMFTM = GetDlgItem(hwndDlg, IDD_DCOMFTM);
  763. if( SendMessage(hDCOMFTM, BM_GETSTATE, 0, 0L) ){
  764. g_fAppCompatGoo = TRUE;
  765. AppCompatFlag.LowPart |= KACF_FTMFROMCURRENTAPT;
  766. }
  767. hOldPathName = GetDlgItem(hwndDlg, IDD_OLDPATH);
  768. if( SendMessage(hOldPathName, BM_GETSTATE, 0, 0L) ){
  769. g_fAppCompatGoo = TRUE;
  770. AppCompatFlag.LowPart |= KACF_OLDGETSHORTPATHNAME;
  771. }
  772. #endif
  773. hCheck3 = GetDlgItem(hwndDlg, IDD_CHECK3);
  774. if( SendMessage(hCheck3, BM_GETSTATE, 0, 0L) == 0)
  775. g_fNotPermanent = TRUE;
  776. if(g_fAppCompatGoo)
  777. MakeAppCompatGoo(EditCtrlBuf,&AppCompatFlag,uOsVerID);
  778. /* Set the ENVIRONMENT Variable "_COMPAT_VER_NNN"
  779. flag with the version checked before calling
  780. ShellExecuteEx()
  781. */
  782. if(SetEnvironmentVariable(TEXT("_COMPAT_VER_NNN"), pEnvVal) == 0){
  783. dwEnvSetError = GetLastError();
  784. if( ERROR_ENVVAR_NOT_FOUND != dwEnvSetError )
  785. DetailError( GetLastError() );
  786. }
  787. if( g_fNotPermanent){
  788. ExecuteApp(hwndDlg, EditCtrlBuf,szTitle,szCommandLine, TRUE);
  789. }
  790. else{
  791. ExecuteApp(hwndDlg, EditCtrlBuf,szTitle,szCommandLine, FALSE);
  792. }
  793. EndDialog(hwndDlg, 0);
  794. }
  795. }
  796. break;
  797. case IDD_CLOSE:
  798. EndDialog(hwndDlg, 0);
  799. }
  800. GlobalFree(g_lpPrevRegSettings);
  801. return TRUE;
  802. }
  803. return FALSE;
  804. }