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.

661 lines
15 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
  6. //
  7. // Other brand and product names used herein are trademarks of their respective owners.
  8. //
  9. // The entire program and user interface including the structure, sequence, selection,
  10. // and arrangement of the dialog, the exclusively "yes" and "no" choices represented
  11. // by "1" and "2," and each dialog message are protected by copyrights registered in
  12. // the United States and by international treaties.
  13. //
  14. // Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
  15. // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. ////
  23. // app.c - Windows command line argument functions
  24. ////
  25. #include "winlocal.h"
  26. #include <stdlib.h>
  27. #include "app.h"
  28. #include "file.h"
  29. #include "loadlib.h"
  30. #include "mem.h"
  31. #include "str.h"
  32. #include "sys.h"
  33. #include "trace.h"
  34. ////
  35. // private definitions
  36. ////
  37. // app control struct
  38. //
  39. typedef struct APP
  40. {
  41. DWORD dwVersion;
  42. HINSTANCE hInst;
  43. HTASK hTask;
  44. LPTSTR lpszFileName;
  45. LPTSTR lpszDirectory;
  46. LPTSTR lpszProfile;
  47. LPTSTR lpszName;
  48. HWND hwndMain;
  49. BOOL fCtl3dEnabled;
  50. HINSTANCE hInstCtl3d;
  51. } APP, FAR *LPAPP;
  52. // helper functions
  53. //
  54. static LPAPP AppGetPtr(HAPP hApp);
  55. static HAPP AppGetHandle(LPAPP lpApp);
  56. ////
  57. // public functions
  58. ////
  59. // AppInit - initialize app engine
  60. // <dwVersion> (i) must be APP_VERSION
  61. // <hInst> (i) instance handle of calling module
  62. // return handle (NULL if error)
  63. //
  64. HAPP DLLEXPORT WINAPI AppInit(DWORD dwVersion, HINSTANCE hInst)
  65. {
  66. BOOL fSuccess = TRUE;
  67. LPAPP lpApp = NULL;
  68. if (dwVersion != APP_VERSION)
  69. fSuccess = TraceFALSE(NULL);
  70. else if (hInst == NULL)
  71. fSuccess = TraceFALSE(NULL);
  72. else if ((lpApp = (LPAPP) MemAlloc(NULL, sizeof(APP), 0)) == NULL)
  73. fSuccess = TraceFALSE(NULL);
  74. else
  75. {
  76. TCHAR szPath[_MAX_PATH];
  77. TCHAR szDrive[_MAX_DRIVE];
  78. TCHAR szDir[_MAX_DIR];
  79. TCHAR szFname[_MAX_FNAME];
  80. TCHAR szExt[_MAX_EXT];
  81. lpApp->dwVersion = dwVersion;
  82. lpApp->hInst = hInst;
  83. lpApp->hTask = GetCurrentTask();
  84. lpApp->lpszFileName = NULL;
  85. lpApp->lpszDirectory = NULL;
  86. lpApp->lpszProfile = NULL;
  87. lpApp->lpszName = NULL;
  88. lpApp->hwndMain = NULL;
  89. #ifdef _WIN32
  90. lpApp->fCtl3dEnabled = (BOOL) (SysGetWindowsVersion() >= 400);
  91. #else
  92. lpApp->fCtl3dEnabled = FALSE;
  93. #endif
  94. lpApp->hInstCtl3d = NULL;
  95. // get the full path of app executable
  96. //
  97. if (GetModuleFileName(hInst, szPath, SIZEOFARRAY(szPath)) <= 0)
  98. fSuccess = TraceFALSE(NULL);
  99. else if ((lpApp->lpszFileName = StrDup(szPath)) == NULL)
  100. fSuccess = TraceFALSE(NULL);
  101. else if (FileSplitPath(szPath,
  102. szDrive, szDir, szFname, szExt) != 0)
  103. fSuccess = TraceFALSE(NULL);
  104. // get default app name
  105. //
  106. else if ((lpApp->lpszName = StrDup(szFname)) == NULL)
  107. fSuccess = TraceFALSE(NULL);
  108. // construct path to app directory
  109. //
  110. else if (FileMakePath(szPath,
  111. szDrive, szDir, NULL, NULL) != 0)
  112. fSuccess = TraceFALSE(NULL);
  113. else if ((lpApp->lpszDirectory = StrDup(szPath)) == NULL)
  114. fSuccess = TraceFALSE(NULL);
  115. // construct path to app ini file
  116. //
  117. else if (AppDirectoryIsReadOnly(AppGetHandle(lpApp)) &&
  118. FileMakePath(szPath, NULL, NULL, szFname, TEXT("ini")) != 0)
  119. fSuccess = TraceFALSE(NULL);
  120. else if (!AppDirectoryIsReadOnly(AppGetHandle(lpApp)) &&
  121. FileMakePath(szPath, szDrive, szDir, szFname, TEXT("ini")) != 0)
  122. fSuccess = TraceFALSE(NULL);
  123. else if ((lpApp->lpszProfile = StrDup(szPath)) == NULL)
  124. fSuccess = TraceFALSE(NULL);
  125. }
  126. if (!fSuccess)
  127. {
  128. AppTerm(AppGetHandle(lpApp));
  129. lpApp = NULL;
  130. }
  131. return fSuccess ? AppGetHandle(lpApp) : NULL;
  132. }
  133. // AppTerm - shut down app engine
  134. // <hApp> (i) handle returned from AppInit
  135. // return 0 if success
  136. //
  137. int DLLEXPORT WINAPI AppTerm(HAPP hApp)
  138. {
  139. BOOL fSuccess = TRUE;
  140. LPAPP lpApp;
  141. if ((lpApp = AppGetPtr(hApp)) == NULL)
  142. fSuccess = TraceFALSE(NULL);
  143. else
  144. {
  145. // shut down Ctl3d if necessary
  146. //
  147. if (AppEnable3dControls(hApp, FALSE, 0) != 0)
  148. fSuccess = TraceFALSE(NULL);
  149. if (lpApp->lpszFileName != NULL)
  150. {
  151. StrDupFree(lpApp->lpszFileName);
  152. lpApp->lpszFileName = NULL;
  153. }
  154. if (lpApp->lpszDirectory != NULL)
  155. {
  156. StrDupFree(lpApp->lpszDirectory);
  157. lpApp->lpszDirectory = NULL;
  158. }
  159. if (lpApp->lpszProfile != NULL)
  160. {
  161. StrDupFree(lpApp->lpszProfile);
  162. lpApp->lpszProfile = NULL;
  163. }
  164. if (lpApp->lpszName != NULL)
  165. {
  166. StrDupFree(lpApp->lpszName);
  167. lpApp->lpszName = NULL;
  168. }
  169. if ((lpApp = MemFree(NULL, lpApp)) != NULL)
  170. fSuccess = TraceFALSE(NULL);
  171. }
  172. return fSuccess ? 0 : -1;
  173. }
  174. // AppGetInstance - get instance handle
  175. // <hApp> (i) handle returned from AppInit
  176. // return instance handle, NULL if error
  177. //
  178. HINSTANCE DLLEXPORT WINAPI AppGetInstance(HAPP hApp)
  179. {
  180. BOOL fSuccess = TRUE;
  181. LPAPP lpApp;
  182. HINSTANCE hInst;
  183. if ((lpApp = AppGetPtr(hApp)) == NULL)
  184. fSuccess = TraceFALSE(NULL);
  185. else
  186. hInst = lpApp->hInst;
  187. return fSuccess ? hInst : NULL;
  188. }
  189. // AppGetFileName - get full path of application executable
  190. // <hApp> (i) handle returned from AppInit
  191. // return pointer to app file name, NULL if error
  192. //
  193. LPCTSTR DLLEXPORT WINAPI AppGetFileName(HAPP hApp)
  194. {
  195. BOOL fSuccess = TRUE;
  196. LPAPP lpApp;
  197. LPTSTR lpszFileName;
  198. if ((lpApp = AppGetPtr(hApp)) == NULL)
  199. fSuccess = TraceFALSE(NULL);
  200. else
  201. lpszFileName = lpApp->lpszFileName;
  202. return fSuccess ? lpszFileName : NULL;
  203. }
  204. // AppGetDirectory - get drive and directory of application executable
  205. // <hApp> (i) handle returned from AppInit
  206. // return pointer to app path, NULL if error
  207. //
  208. LPCTSTR DLLEXPORT WINAPI AppGetDirectory(HAPP hApp)
  209. {
  210. BOOL fSuccess = TRUE;
  211. LPAPP lpApp;
  212. LPTSTR lpszDirectory;
  213. if ((lpApp = AppGetPtr(hApp)) == NULL)
  214. fSuccess = TraceFALSE(NULL);
  215. else
  216. lpszDirectory = lpApp->lpszDirectory;
  217. return fSuccess ? lpszDirectory : NULL;
  218. }
  219. // AppDirectoryIsReadOnly - test if application directory is read-only
  220. // <hApp> (i) handle returned from AppInit
  221. // return TRUE if read-only, otherwise FALSE
  222. //
  223. BOOL DLLEXPORT WINAPI AppDirectoryIsReadOnly(HAPP hApp)
  224. {
  225. BOOL fSuccess = TRUE;
  226. LPAPP lpApp;
  227. BOOL fIsReadOnly;
  228. TCHAR szPath[_MAX_PATH];
  229. if ((lpApp = AppGetPtr(hApp)) == NULL)
  230. fSuccess = TraceFALSE(NULL);
  231. else if (FileMakePath(szPath, NULL,
  232. AppGetDirectory(hApp), TEXT("readonly"), TEXT("ini")) != 0)
  233. fSuccess = TraceFALSE(NULL);
  234. else
  235. {
  236. // [ReadOnly]
  237. // ReadOnly=1
  238. //
  239. fIsReadOnly = (BOOL) GetPrivateProfileInt(TEXT("ReadOnly"),
  240. TEXT("ReadOnly"), 0, szPath);
  241. }
  242. return fSuccess ? fIsReadOnly : FALSE;
  243. }
  244. // AppGetProfile - get ini filename of application
  245. // <hApp> (i) handle returned from AppInit
  246. // return pointer to app profile, NULL if error
  247. //
  248. // NOTE: by default, the filename returned by this function
  249. // has the same file path and name as the application executable,
  250. // with a ".ini" extension. If the application directory is
  251. // read-only, the Windows directory is used instead.
  252. // To override the default, use the AppSetProfile() function.
  253. //
  254. LPCTSTR DLLEXPORT WINAPI AppGetProfile(HAPP hApp)
  255. {
  256. BOOL fSuccess = TRUE;
  257. LPAPP lpApp;
  258. LPTSTR lpszProfile;
  259. if ((lpApp = AppGetPtr(hApp)) == NULL)
  260. fSuccess = TraceFALSE(NULL);
  261. else
  262. lpszProfile = lpApp->lpszProfile;
  263. return fSuccess ? lpszProfile : NULL;
  264. }
  265. // AppSetProfile - set ini filename of application
  266. // <hApp> (i) handle returned from AppInit
  267. // <lpszProfile> (i) ini filename
  268. // return 0 if success
  269. //
  270. int DLLEXPORT WINAPI AppSetProfile(HAPP hApp, LPCTSTR lpszProfile)
  271. {
  272. BOOL fSuccess = TRUE;
  273. LPAPP lpApp;
  274. if ((lpApp = AppGetPtr(hApp)) == NULL)
  275. fSuccess = TraceFALSE(NULL);
  276. else
  277. {
  278. // save old profile
  279. //
  280. LPTSTR lpszProfileOld = lpApp->lpszProfile;
  281. // set new profile
  282. //
  283. if ((lpApp->lpszProfile = StrDup(lpszProfile)) == NULL)
  284. {
  285. fSuccess = TraceFALSE(NULL);
  286. // restore old profile if error
  287. //
  288. lpApp->lpszProfile = lpszProfileOld;
  289. }
  290. // free old profile
  291. //
  292. else if (lpszProfileOld != NULL)
  293. {
  294. StrDupFree(lpszProfileOld);
  295. lpszProfileOld = NULL;
  296. }
  297. }
  298. return fSuccess ? 0 : -1;
  299. }
  300. // AppGetName - get name of application
  301. // <hApp> (i) handle returned from AppInit
  302. // return pointer to app profile, NULL if error
  303. //
  304. // NOTE: by default, the name returned by this function
  305. // has the same root name as the application executable,
  306. // with no extension. To override the default, use the
  307. // AppSetName() function.
  308. //
  309. LPCTSTR DLLEXPORT WINAPI AppGetName(HAPP hApp)
  310. {
  311. BOOL fSuccess = TRUE;
  312. LPAPP lpApp;
  313. LPTSTR lpszName;
  314. if ((lpApp = AppGetPtr(hApp)) == NULL)
  315. fSuccess = TraceFALSE(NULL);
  316. else
  317. lpszName = lpApp->lpszName;
  318. return fSuccess ? lpszName : NULL;
  319. }
  320. // AppSetName - set name of application
  321. // <hApp> (i) handle returned from AppInit
  322. // <lpszName> (i) application name
  323. // return 0 if success
  324. //
  325. int DLLEXPORT WINAPI AppSetName(HAPP hApp, LPCTSTR lpszName)
  326. {
  327. BOOL fSuccess = TRUE;
  328. LPAPP lpApp;
  329. if ((lpApp = AppGetPtr(hApp)) == NULL)
  330. fSuccess = TraceFALSE(NULL);
  331. else
  332. {
  333. // save old name
  334. //
  335. LPTSTR lpszNameOld = lpApp->lpszName;
  336. // set new name
  337. //
  338. if ((lpApp->lpszName = StrDup(lpszName)) == NULL)
  339. {
  340. fSuccess = TraceFALSE(NULL);
  341. // restore old name if error
  342. //
  343. lpApp->lpszName = lpszNameOld;
  344. }
  345. // free old name
  346. //
  347. else if (lpszNameOld != NULL)
  348. {
  349. StrDupFree(lpszNameOld);
  350. lpszNameOld = NULL;
  351. }
  352. }
  353. return fSuccess ? 0 : -1;
  354. }
  355. // AppGetMainWnd - get main window of application
  356. // <hApp> (i) handle returned from AppInit
  357. // return window handle, NULL if error or none
  358. //
  359. HWND DLLEXPORT WINAPI AppGetMainWnd(HAPP hApp)
  360. {
  361. BOOL fSuccess = TRUE;
  362. LPAPP lpApp;
  363. HWND hwndMain;
  364. if ((lpApp = AppGetPtr(hApp)) == NULL)
  365. fSuccess = TraceFALSE(NULL);
  366. else
  367. hwndMain = lpApp->hwndMain;
  368. return fSuccess ? hwndMain : NULL;
  369. }
  370. // AppSetMainWnd - set main window of application
  371. // <hApp> (i) handle returned from AppInit
  372. // <hwndMain> (i) handle to main window
  373. // return 0 if success
  374. //
  375. int DLLEXPORT WINAPI AppSetMainWnd(HAPP hApp, HWND hwndMain)
  376. {
  377. BOOL fSuccess = TRUE;
  378. LPAPP lpApp;
  379. if ((lpApp = AppGetPtr(hApp)) == NULL)
  380. fSuccess = TraceFALSE(NULL);
  381. else
  382. lpApp->hwndMain = hwndMain;
  383. return fSuccess ? 0 : -1;
  384. }
  385. // ctl3d stuff
  386. //
  387. #ifdef _WIN32
  388. #define CTL3D_LIBRARY TEXT("ctl3d32.dll")
  389. #else
  390. #define CTL3D_LIBRARY TEXT("ctl3dv2.dll")
  391. #endif
  392. typedef BOOL (WINAPI* LPFNCTL3D)();
  393. // AppEnable3dControls - give standard controls a 3d appearance
  394. // <hApp> (i) handle returned from AppInit
  395. // <fEnable> (i) TRUE to enable, FALSE to disable
  396. // <dwFlags> (i) control flags
  397. // 0 reserved; must be zero
  398. // return 0 if success, -1 if error
  399. //
  400. int DLLEXPORT WINAPI AppEnable3dControls(HAPP hApp, BOOL fEnable, DWORD dwFlags)
  401. {
  402. BOOL fSuccess = TRUE;
  403. LPAPP lpApp;
  404. if ((lpApp = AppGetPtr(hApp)) == NULL)
  405. fSuccess = TraceFALSE(NULL);
  406. #ifdef _WIN32
  407. // nothing to do if OS already supports 3d controls
  408. //
  409. else if (SysGetWindowsVersion() >= 400)
  410. lpApp->fCtl3dEnabled = fEnable;
  411. #endif
  412. // enable 3d controls unless they already are enabled
  413. //
  414. else if (fEnable && !lpApp->fCtl3dEnabled)
  415. {
  416. LPFNCTL3D lpfnCtl3dRegister;
  417. LPFNCTL3D lpfnCtl3dAutoSubclass;
  418. if (lpApp->hInstCtl3d != NULL)
  419. fSuccess = TraceFALSE(NULL);
  420. else if ((lpApp->hInstCtl3d = LoadLibraryPath(CTL3D_LIBRARY,
  421. NULL, 0)) == NULL)
  422. fSuccess = TraceFALSE(NULL);
  423. else if ((lpfnCtl3dRegister = (LPFNCTL3D) GetProcAddress(
  424. lpApp->hInstCtl3d, "Ctl3dRegister")) == NULL)
  425. fSuccess = TraceFALSE(NULL);
  426. else if (!((*lpfnCtl3dRegister)(lpApp->hInstCtl3d)))
  427. fSuccess = TraceFALSE(NULL);
  428. else if ((lpfnCtl3dAutoSubclass = (LPFNCTL3D) GetProcAddress(
  429. lpApp->hInstCtl3d, "Ctl3dAutoSubclass")) == NULL)
  430. fSuccess = TraceFALSE(NULL);
  431. else if (!((*lpfnCtl3dAutoSubclass)(lpApp->hInstCtl3d)))
  432. fSuccess = TraceFALSE(NULL);
  433. else
  434. lpApp->fCtl3dEnabled = TRUE;
  435. }
  436. // disable 3d controls unless they already are disabled
  437. //
  438. else if (!fEnable && lpApp->fCtl3dEnabled)
  439. {
  440. LPFNCTL3D lpfnCtl3dUnregister;
  441. if (lpApp->hInstCtl3d == NULL)
  442. fSuccess = TraceFALSE(NULL);
  443. else if ((lpfnCtl3dUnregister = (LPFNCTL3D) GetProcAddress(
  444. lpApp->hInstCtl3d, "Ctl3dUnregister")) == NULL)
  445. fSuccess = TraceFALSE(NULL);
  446. else if (!((*lpfnCtl3dUnregister)(lpApp->hInstCtl3d)))
  447. fSuccess = TraceFALSE(NULL);
  448. #ifdef _WIN32
  449. else if (!FreeLibrary(lpApp->hInstCtl3d))
  450. {
  451. fSuccess = TraceFALSE(NULL);
  452. TracePrintf_2(NULL, 5,
  453. TEXT("FreeLibrary(\"%s\") failed (%lu)\n"),
  454. (LPTSTR) CTL3D_LIBRARY,
  455. (unsigned long) GetLastError());
  456. }
  457. #else
  458. else if (FreeLibrary(lpApp->hInstCtl3d), FALSE)
  459. ;
  460. #endif
  461. else
  462. {
  463. lpApp->hInstCtl3d = NULL;
  464. lpApp->fCtl3dEnabled = FALSE;
  465. }
  466. }
  467. return fSuccess ? 0 : -1;
  468. }
  469. // AppIs3dControlsEnabled - return TRUE if 3d controls enabled
  470. // <hApp> (i) handle returned from AppInit
  471. // return TRUE if 3d controls enabled, otherwise FALSE
  472. //
  473. BOOL DLLEXPORT WINAPI AppIs3dControlsEnabled(HAPP hApp)
  474. {
  475. BOOL fSuccess = TRUE;
  476. LPAPP lpApp;
  477. BOOL fEnabled;
  478. if ((lpApp = AppGetPtr(hApp)) == NULL)
  479. fSuccess = TraceFALSE(NULL);
  480. else
  481. fEnabled = lpApp->fCtl3dEnabled;
  482. return fSuccess ? fEnabled : FALSE;
  483. }
  484. // AppOnSysColorChange - handler for WM_SYSCOLORCHANGE message
  485. // <hApp> (i) handle returned from AppInit
  486. // return 0 if success
  487. //
  488. LRESULT DLLEXPORT WINAPI AppOnSysColorChange(HAPP hApp)
  489. {
  490. BOOL fSuccess = TRUE;
  491. LPAPP lpApp;
  492. if ((lpApp = AppGetPtr(hApp)) == NULL)
  493. fSuccess = TraceFALSE(NULL);
  494. else if (lpApp->fCtl3dEnabled)
  495. {
  496. LPFNCTL3D lpfnCtl3dColorChange;
  497. if (lpApp->hInstCtl3d == NULL)
  498. fSuccess = TraceFALSE(NULL);
  499. else if ((lpfnCtl3dColorChange = (LPFNCTL3D) GetProcAddress(
  500. lpApp->hInstCtl3d, "Ctl3dColorChange")) == NULL)
  501. fSuccess = TraceFALSE(NULL);
  502. else if (!((*lpfnCtl3dColorChange)()))
  503. fSuccess = TraceFALSE(NULL);
  504. }
  505. return fSuccess ? 0 : -1;
  506. }
  507. ////
  508. // helper functions
  509. ////
  510. // AppGetPtr - verify that arg handle is valid,
  511. // <hApp> (i) handle returned from AppInit
  512. // return corresponding arg pointer (NULL if error)
  513. //
  514. static LPAPP AppGetPtr(HAPP hApp)
  515. {
  516. BOOL fSuccess = TRUE;
  517. LPAPP lpApp;
  518. if ((lpApp = (LPAPP) hApp) == NULL)
  519. fSuccess = TraceFALSE(NULL);
  520. else if (IsBadWritePtr(lpApp, sizeof(APP)))
  521. fSuccess = TraceFALSE(NULL);
  522. #ifdef CHECKTASK
  523. // make sure current task owns the arg handle
  524. //
  525. else if (lpApp->hTask != GetCurrentTask())
  526. fSuccess = TraceFALSE(NULL);
  527. #endif
  528. return fSuccess ? lpApp : NULL;
  529. }
  530. // AppGetHandle - verify that arg pointer is valid,
  531. // <lpApp> (i) pointer to APP struct
  532. // return corresponding arg handle (NULL if error)
  533. //
  534. static HAPP AppGetHandle(LPAPP lpApp)
  535. {
  536. BOOL fSuccess = TRUE;
  537. HAPP hApp;
  538. if ((hApp = (HAPP) lpApp) == NULL)
  539. fSuccess = TraceFALSE(NULL);
  540. return fSuccess ? hApp : NULL;
  541. }