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.

814 lines
24 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WKERNEL.C
  8. * WOW32 16-bit Kernel API support
  9. *
  10. * History:
  11. * Created 07-Mar-1991 by Jeff Parsons (jeffpar)
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. MODNAME(wkernel.c);
  16. ULONG FASTCALL WK32WritePrivateProfileString(PVDMFRAME pFrame)
  17. {
  18. ULONG ul;
  19. PSZ pszSection;
  20. PSZ pszKey;
  21. PSZ pszValue;
  22. PSZ pszFilename;
  23. register PWRITEPRIVATEPROFILESTRING16 parg16;
  24. BOOL fIsWinIni;
  25. CHAR szLowercase[MAX_PATH];
  26. GETARGPTR(pFrame, sizeof(WRITEPRIVATEPROFILESTRING16), parg16);
  27. GETPSZPTR(parg16->f1, pszSection);
  28. GETPSZPTR(parg16->f2, pszKey);
  29. GETPSZPTR(parg16->f3, pszValue);
  30. GETPSZPTR(parg16->f4, pszFilename);
  31. UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
  32. strcpy(szLowercase, pszFilename);
  33. WOW32_strlwr(szLowercase);
  34. fIsWinIni = IS_WIN_INI(szLowercase);
  35. // Trying to install or change default printer to fax printer?
  36. if (fIsWinIni &&
  37. pszSection &&
  38. pszKey &&
  39. pszValue &&
  40. !WOW32_stricmp(pszSection, szDevices) &&
  41. IsFaxPrinterWriteProfileString(pszSection, pszKey, pszValue)) {
  42. ul = TRUE;
  43. goto Done;
  44. }
  45. ul = GETBOOL16( WritePrivateProfileString(
  46. pszSection,
  47. pszKey,
  48. pszValue,
  49. pszFilename
  50. ));
  51. if( ul != 0 &&
  52. fIsWinIni &&
  53. IS_EMBEDDING_SECTION( pszSection ) &&
  54. pszKey != NULL &&
  55. pszValue != NULL ) {
  56. UpdateClassesRootSubKey( pszKey, pszValue);
  57. }
  58. Done:
  59. FREEPSZPTR(pszSection);
  60. FREEPSZPTR(pszKey);
  61. FREEPSZPTR(pszValue);
  62. FREEPSZPTR(pszFilename);
  63. FREEARGPTR(parg16);
  64. return ul;
  65. }
  66. ULONG FASTCALL WK32WriteProfileString(PVDMFRAME pFrame)
  67. {
  68. ULONG ul;
  69. PSZ pszSection;
  70. PSZ pszKey;
  71. PSZ pszValue;
  72. register PWRITEPROFILESTRING16 parg16;
  73. GETARGPTR(pFrame, sizeof(WRITEPROFILESTRING16), parg16);
  74. GETPSZPTR(parg16->f1, pszSection);
  75. GETPSZPTR(parg16->f2, pszKey);
  76. GETPSZPTR(parg16->f3, pszValue);
  77. // For WinFax Lite install hack. Bug #126489 See wow32fax.c
  78. if(!gbWinFaxHack) {
  79. // Trying to install or change default printer to fax printer?
  80. if (pszSection &&
  81. pszKey &&
  82. pszValue &&
  83. !WOW32_stricmp(pszSection, szDevices) &&
  84. IsFaxPrinterWriteProfileString(pszSection, pszKey, pszValue)) {
  85. ul = TRUE;
  86. goto Done;
  87. }
  88. } else {
  89. IsFaxPrinterWriteProfileString(pszSection, pszKey, pszValue);
  90. }
  91. ul = GETBOOL16( WriteProfileString(
  92. pszSection,
  93. pszKey,
  94. pszValue
  95. ));
  96. if( ( ul != 0 ) &&
  97. IS_EMBEDDING_SECTION( pszSection ) &&
  98. ( pszKey != NULL ) &&
  99. ( pszValue != NULL ) ) {
  100. UpdateClassesRootSubKey( pszKey, pszValue);
  101. }
  102. Done:
  103. FREEPSZPTR(pszSection);
  104. FREEPSZPTR(pszKey);
  105. FREEPSZPTR(pszValue);
  106. FREEARGPTR(parg16);
  107. return ul;
  108. }
  109. ULONG FASTCALL WK32GetProfileString(PVDMFRAME pFrame)
  110. {
  111. ULONG ul;
  112. PSZ pszSection;
  113. PSZ pszKey;
  114. PSZ pszDefault;
  115. PSZ pszReturnBuffer;
  116. UINT cchMax;
  117. #ifdef FE_SB
  118. PSZ pszTmp = NULL;
  119. #endif // FE_SB
  120. register PGETPROFILESTRING16 parg16;
  121. GETARGPTR(pFrame, sizeof(GETPROFILESTRING16), parg16);
  122. GETPSZPTR(parg16->f1, pszSection);
  123. GETPSZPTR(parg16->f2, pszKey);
  124. GETPSZPTR(parg16->f3, pszDefault);
  125. ALLOCVDMPTR(parg16->f4, parg16->f5, pszReturnBuffer);
  126. cchMax = INT32(parg16->f5);
  127. #ifdef FE_SB
  128. //
  129. // For those applications that expect sLongDate contains
  130. // windows 3.1J picture format string.
  131. //
  132. if (GetSystemDefaultLangID() == 0x411 &&
  133. !lstrcmpi(pszSection, "intl") && !lstrcmpi(pszKey, "sLongDate")) {
  134. pszTmp = pszKey;
  135. pszKey = "sLongDate16";
  136. }
  137. #endif // FE_SB
  138. if (IS_EMBEDDING_SECTION( pszSection ) &&
  139. !WasSectionRecentlyUpdated() ) {
  140. if( pszKey == NULL ) {
  141. UpdateEmbeddingAllKeys();
  142. } else {
  143. UpdateEmbeddingKey( pszKey );
  144. }
  145. SetLastTimeUpdated();
  146. } else if (pszSection &&
  147. pszKey &&
  148. !WOW32_stricmp(pszSection, szDevices) &&
  149. IsFaxPrinterSupportedDevice(pszKey)) {
  150. ul = GETINT16(GetFaxPrinterProfileString(pszSection, pszKey, pszDefault, pszReturnBuffer, cchMax));
  151. goto FlushAndReturn;
  152. }
  153. ul = GETINT16(GetProfileString(
  154. pszSection,
  155. pszKey,
  156. pszDefault,
  157. pszReturnBuffer,
  158. cchMax));
  159. //
  160. // Win3.1/Win95 compatibility: Zap the first trailing blank in pszDefault
  161. // with null, but only if the default string was returned. To detect
  162. // the default string being returned we need to ignore trailing blanks.
  163. //
  164. // This code is duplicated in thunks for GetProfileString and
  165. // GetPrivateProfileString, update both if you make changes.
  166. //
  167. if ( pszDefault && pszKey ) {
  168. int n, nLenDef;
  169. //
  170. // Is the default the same as the returned string up to any NULLs?
  171. //
  172. nLenDef = 0;
  173. n=0;
  174. while (
  175. (pszDefault[nLenDef] == pszReturnBuffer[n]) &&
  176. pszReturnBuffer[n]
  177. ) {
  178. n++;
  179. nLenDef++;
  180. }
  181. //
  182. // Did we get out of the loop because we're at the end of the returned string?
  183. //
  184. if ( '\0' != pszReturnBuffer[n] ) {
  185. //
  186. // No. The strings are materially different - fall out.
  187. //
  188. }
  189. else {
  190. //
  191. // Ok, the strings are identical to the end of the returned string.
  192. // Is the default string spaces out to the end?
  193. //
  194. while ( ' ' == pszDefault[nLenDef] ) {
  195. nLenDef++;
  196. }
  197. //
  198. // The last thing was not a space. If it was a NULL, then the app
  199. // passed in a string with trailing NULLs as default. (Otherwise
  200. // the two strings are materially different and we do nothing.)
  201. //
  202. if ( '\0' == pszDefault[nLenDef] ) {
  203. char szBuf[4]; // Some random, small number of chars to get.
  204. // If the string is long, we'll get only 3 chars
  205. // (and NULL), but so what? - we only need to know if
  206. // we got a default last time...
  207. //
  208. // The returned string is the same as the default string
  209. // without trailing blanks, but this might be coincidence,
  210. // so see if a call with empty pszDefault returns anything.
  211. // If it does, we don't zap because the default isn't
  212. // being used.
  213. //
  214. if (0 == GetProfileString(pszSection, pszKey, "", szBuf, sizeof(szBuf))) {
  215. //
  216. // Zap first trailing blank in pszDefault with null.
  217. //
  218. pszDefault[ul] = 0;
  219. FLUSHVDMPTR(parg16->f3 + ul, 1, pszDefault + ul);
  220. }
  221. }
  222. }
  223. }
  224. FlushAndReturn:
  225. #ifdef FE_SB
  226. if ( pszTmp )
  227. pszKey = pszTmp;
  228. if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_USEUPPER) { // for WinWrite
  229. if (pszSection && !lstrcmpi(pszSection, "windows") &&
  230. pszKey && !lstrcmpi(pszKey, "device")) {
  231. CharUpper(pszReturnBuffer);
  232. }
  233. if (pszSection && !lstrcmpi(pszSection, "devices") && pszKey) {
  234. CharUpper(pszReturnBuffer);
  235. }
  236. }
  237. #endif // FE_SB
  238. FLUSHVDMPTR(parg16->f4, (ul + (pszSection && pszKey) ? 1 : 2), pszReturnBuffer);
  239. FREEPSZPTR(pszSection);
  240. FREEPSZPTR(pszKey);
  241. FREEPSZPTR(pszDefault);
  242. FREEVDMPTR(pszReturnBuffer);
  243. FREEARGPTR(parg16);
  244. RETURN(ul);
  245. }
  246. ULONG FASTCALL WK32GetPrivateProfileString(PVDMFRAME pFrame)
  247. {
  248. ULONG ul;
  249. PSZ pszSection;
  250. PSZ pszKey;
  251. PSZ pszDefault;
  252. PSZ pszReturnBuffer;
  253. PSZ pszFilename;
  254. UINT cchMax;
  255. #ifdef FE_SB
  256. PSZ pszTmp = NULL;
  257. #endif // FE_SB
  258. register PGETPRIVATEPROFILESTRING16 parg16;
  259. CHAR szLowercase[MAX_PATH];
  260. GETARGPTR(pFrame, sizeof(GETPRIVATEPROFILESTRING16), parg16);
  261. GETPSZPTR(parg16->f1, pszSection);
  262. GETPSZPTR(parg16->f2, pszKey);
  263. GETPSZPTR(parg16->f3, pszDefault);
  264. ALLOCVDMPTR(parg16->f4, parg16->f5, pszReturnBuffer);
  265. GETPSZPTR(parg16->f6, pszFilename);
  266. // PC3270 (Personal communications): while installing this app it calls
  267. // GetPrivateProfileString (sectionname, NULL, defaultbuffer, returnbuffer,
  268. // cch = 0, filename). On win31 this call returns relevant data in return
  269. // buffer and corresponding size as return value. On NT, since the
  270. // buffersize(cch) is '0' no data is copied into the return buffer and
  271. // return value is zero which makes this app abort installation.
  272. //
  273. // So restricted compatibility:
  274. // if above is the case set
  275. // cch = 64k - offset of returnbuffer;
  276. //
  277. // A safer 'cch' would be
  278. // cch = GlobalSize(selector of returnbuffer) -
  279. // (offset of returnbuffer);
  280. // - nanduri
  281. if (!(cchMax = INT32(parg16->f5))) {
  282. if (pszKey == (PSZ)NULL) {
  283. if (pszReturnBuffer != (PSZ)NULL) {
  284. cchMax = 0xffff - (LOW16(parg16->f4));
  285. }
  286. }
  287. }
  288. UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
  289. strcpy(szLowercase, pszFilename);
  290. WOW32_strlwr(szLowercase);
  291. if (IS_WIN_INI( szLowercase )) {
  292. #ifdef FE_SB
  293. //
  294. // For those applications that expect sLongDate contains
  295. // windows 3.1J picture format string.
  296. //
  297. if (GetSystemDefaultLangID() == 0x411 &&
  298. lstrcmpi( pszSection, "intl") == 0 &&
  299. lstrcmpi( pszKey, "sLongDate") == 0) {
  300. pszTmp = pszKey;
  301. pszKey = "sLongDate16";
  302. }
  303. #endif // FE_SB
  304. if (IS_EMBEDDING_SECTION( pszSection ) &&
  305. !WasSectionRecentlyUpdated() ) {
  306. if( pszKey == NULL ) {
  307. UpdateEmbeddingAllKeys();
  308. } else {
  309. UpdateEmbeddingKey( pszKey );
  310. }
  311. SetLastTimeUpdated();
  312. } else if (pszSection &&
  313. pszKey &&
  314. !WOW32_stricmp(pszSection, szDevices) &&
  315. IsFaxPrinterSupportedDevice(pszKey)) {
  316. ul = GETINT16(GetFaxPrinterProfileString(pszSection, pszKey, pszDefault, pszReturnBuffer, cchMax));
  317. goto FlushAndReturn;
  318. }
  319. }
  320. ul = GETUINT16(GetPrivateProfileString(
  321. pszSection,
  322. pszKey,
  323. pszDefault,
  324. pszReturnBuffer,
  325. cchMax,
  326. pszFilename));
  327. // start comaptibility hacks
  328. //
  329. // Win3.1/Win95 compatibility: Zap the first trailing blank in pszDefault
  330. // with null, but only if the default string was returned. To detect
  331. // the default string being returned we need to ignore trailing blanks.
  332. //
  333. // This code is duplicated in thunks for GetProfileString and
  334. // GetPrivateProfileString, update both if you make changes.
  335. //
  336. if ( pszDefault && pszKey ) {
  337. int n, nLenDef;
  338. //
  339. // Is the default the same as the returned string up to any NULLs?
  340. //
  341. nLenDef = 0;
  342. n=0;
  343. while (
  344. (pszDefault[nLenDef] == pszReturnBuffer[n]) &&
  345. pszReturnBuffer[n]
  346. ) {
  347. n++;
  348. nLenDef++;
  349. }
  350. //
  351. // Did we get out of the loop because we're at the end of the returned string?
  352. //
  353. if ( '\0' != pszReturnBuffer[n] ) {
  354. //
  355. // No. The strings are materially different - fall out.
  356. //
  357. }
  358. else {
  359. //
  360. // Ok, the strings are identical to the end of the returned string.
  361. // Is the default string spaces out to the end?
  362. //
  363. while ( ' ' == pszDefault[nLenDef] ) {
  364. nLenDef++;
  365. }
  366. //
  367. // The last thing was not a space. If it was a NULL, then the app
  368. // passed in a string with trailing NULLs as default. (Otherwise
  369. // the two strings are materially different and we do nothing.)
  370. //
  371. if ( '\0' == pszDefault[nLenDef] ) {
  372. char szBuf[4]; // Some random, small number of chars to get.
  373. // If the string is long, we'll get only 3 chars
  374. // (and NULL), but so what? - we only need to know if
  375. // we got a default last time...
  376. //
  377. // The returned string is the same as the default string
  378. // without trailing blanks, but this might be coincidence,
  379. // so see if a call with empty pszDefault returns anything.
  380. // If it does, we don't zap because the default isn't
  381. // being used.
  382. //
  383. if (0 == GetProfileString(pszSection, pszKey, "", szBuf, sizeof(szBuf))) {
  384. //
  385. // Zap first trailing blank in pszDefault with null.
  386. //
  387. pszDefault[ul] = 0;
  388. FLUSHVDMPTR(parg16->f3 + ul, 1, pszDefault + ul);
  389. }
  390. }
  391. }
  392. }
  393. if( CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_SAYITSNOTTHERE ) {
  394. // CrossTalk 2.2 gets hung in a loop while trying to match a printer in
  395. // their xtalk.ini file with a printer name in the PrintDlg listbox.
  396. // There is a bug in their code for handling this that gets exposed by
  397. // the fact that NT PrintDlg listboxes do not include the port name as
  398. // Win3.1 & Win'95 do. We avoid the buggy code altogether with this
  399. // hack by telling them that the preferred printer isn't stored in
  400. // xtalk.ini. See bug #43168 a-craigj
  401. // Maximizer 5.0 has similar problem. it tries to parse
  402. // print driver location however, allocates too small buffer. See
  403. // Whistler bug 288491
  404. if(!WOW32_stricmp(pszSection, "Printer")) {
  405. if((WOW32_strstr(szLowercase, "xtalk.ini") && !WOW32_stricmp(pszKey, "Device")) || // CrossTalk 2.2
  406. (WOW32_strstr(szLowercase, "bclwdde.ini") && !WOW32_stricmp(pszKey, "Driver")) ){ // Maximizer 5
  407. strcpy(pszReturnBuffer, pszDefault);
  408. ul = strlen(pszReturnBuffer);
  409. }
  410. }
  411. // WHISTLER RAID BUG # 379253 05/06/2001 - alexsm
  412. // National Geographic Explorer needed the oppisite of the above. The app
  413. // was checking for a QTWVideo string, which contained a path to a quicktime
  414. // driver. Without the key, the app wouldn't play video. It's not really a
  415. // SAYITSNOTTHERE, more of a SAYITISTHERE, but this saves on compat bits.
  416. if(!WOW32_stricmp(pszSection, "mci")) {
  417. if((WOW32_strstr(szLowercase, "system.ini") && !WOW32_stricmp(pszKey, "QTWVideo"))) {
  418. CHAR szMCIQTW[] = "\\system\\mciqtw.drv";
  419. CHAR szQTWVideo[MAX_PATH + sizeof(szMCIQTW) / sizeof(CHAR)]; // make sure there's room for the new string (max_path + pszMCIQTW)
  420. GetSystemWindowsDirectory(szQTWVideo, MAX_PATH);
  421. strcat(szQTWVideo, szMCIQTW);
  422. strncpy(pszReturnBuffer, szQTWVideo, cchMax - 1);
  423. *(pszReturnBuffer + (cchMax - 1)) = '\0';
  424. ul = strlen(szQTWVideo);
  425. }
  426. }
  427. }
  428. FlushAndReturn:
  429. #ifdef FE_SB
  430. if ( pszTmp )
  431. pszKey = pszTmp;
  432. #endif // FE_SB
  433. if (ul) {
  434. FLUSHVDMPTR(parg16->f4, (ul + (pszSection && pszKey) ? 1 : 2), pszReturnBuffer);
  435. LOGDEBUG(8,("GetPrivateProfileString returns '%s'\n", pszReturnBuffer));
  436. }
  437. #ifdef DEBUG
  438. //
  439. // Check for bad return on retrieving entire section by walking
  440. // the section making sure it's full of null-terminated strings
  441. // with an extra null at the end. Also ensure that this all fits
  442. // within the buffer.
  443. //
  444. if (!pszKey) {
  445. PSZ psz;
  446. //
  447. // We don't want to complain if the poorly-formed buffer was the one
  448. // passed in as pszDefault by the caller.
  449. //
  450. // Although the api docs clearly state that pszDefault should never
  451. // be null but win3.1 is nice enough to still deal with this. Delphi is
  452. // passing pszDefault as NULL and this following code causes an
  453. // assertion in WOW. So added the pszDefault check first.
  454. //
  455. // sudeepb 11-Sep-1995
  456. if (!pszDefault || WOW32_strcmp(pszReturnBuffer, pszDefault)) {
  457. psz = pszReturnBuffer;
  458. while (psz < (pszReturnBuffer + ul + 2) && *psz) {
  459. psz += strlen(psz) + 1;
  460. }
  461. WOW32ASSERTMSGF(
  462. psz < (pszReturnBuffer + ul + 2),
  463. ("GetPrivateProfileString of entire section returns poorly formed buffer.\n"
  464. "pszReturnBuffer = %p, return value = %d\n",
  465. pszReturnBuffer,
  466. ul
  467. ));
  468. }
  469. }
  470. #endif // DEBUG
  471. FREEPSZPTR(pszSection);
  472. FREEPSZPTR(pszKey);
  473. FREEPSZPTR(pszDefault);
  474. FREEVDMPTR(pszReturnBuffer);
  475. FREEPSZPTR(pszFilename);
  476. FREEARGPTR(parg16);
  477. RETURN(ul);
  478. }
  479. ULONG FASTCALL WK32GetProfileInt(PVDMFRAME pFrame)
  480. {
  481. ULONG ul;
  482. PSZ psz1;
  483. PSZ psz2;
  484. register PGETPROFILEINT16 parg16;
  485. GETARGPTR(pFrame, sizeof(GETPROFILEINT16), parg16);
  486. GETPSZPTR(parg16->f1, psz1);
  487. GETPSZPTR(parg16->f2, psz2);
  488. ul = GETWORD16(GetProfileInt(
  489. psz1,
  490. psz2,
  491. INT32(parg16->f3)
  492. ));
  493. //
  494. // In HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics, there
  495. // are a bunch of values that define the screen appearance. You can
  496. // watch these values get updated when you go into the display control
  497. // panel applet and change the "appearance scheme", or any of the
  498. // individual elements. The win95 shell is different than win31 in that it
  499. // sticks "twips" values in there instead of pixels. These are calculated
  500. // with the following formula:
  501. //
  502. // twips = - pixels * 72 * 20 / cyPixelsPerInch
  503. //
  504. // pixels = -twips * cyPixelsPerInch / (72*20)
  505. //
  506. // So if the value is negative, it is in twips, otherwise it in pixels.
  507. // The idea is that these values are device independent. NT is
  508. // different than win95 in that we provide an Ini file mapping to this
  509. // section of the registry where win95 does not. Now, when the Lotus
  510. // Freelance Graphics 2.1 tutorial runs, it mucks around with the look
  511. // of the screen, and it changes the border width of window frames by
  512. // using SystemParametersInfo(). When it tries to restore it, it uses
  513. // GetProfileInt("Windows", "BorderWidth", <default>), which on win31
  514. // returns pixels, on win95 returns the default (no ini mapping), and
  515. // on NT returns TWIPS. Since this negative number is interpreted as
  516. // a huge UINT, then the window frames become huge. What this code
  517. // below will do is translate the number back to pixels. [neilsa]
  518. //
  519. if ((CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_PIXELMETRICS) &&
  520. !WOW32_stricmp(psz1, "Windows") &&
  521. !WOW32_stricmp(psz2, "BorderWidth") &&
  522. ((INT)ul < 0)) {
  523. HDC hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  524. if ( !hDC ) {
  525. ul = (ULONG) (-(INT)ul * GetDeviceCaps(hDC, LOGPIXELSY)/(72*20));
  526. DeleteDC(hDC);
  527. }
  528. }
  529. FREEPSZPTR(psz1);
  530. FREEPSZPTR(psz2);
  531. FREEARGPTR(parg16);
  532. RETURN(ul);
  533. }
  534. ULONG FASTCALL WK32GetPrivateProfileInt(PVDMFRAME pFrame)
  535. {
  536. ULONG ul;
  537. PSZ psz1;
  538. PSZ psz2;
  539. PSZ psz4;
  540. register PGETPRIVATEPROFILEINT16 parg16;
  541. GETARGPTR(pFrame, sizeof(GETPRIVATEPROFILEINT16), parg16);
  542. GETPSZPTR(parg16->f1, psz1);
  543. GETPSZPTR(parg16->f2, psz2);
  544. GETPSZPTR(parg16->f4, psz4);
  545. UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
  546. ul = GETWORD16(GetPrivateProfileInt(
  547. psz1,
  548. psz2,
  549. INT32(parg16->f3),
  550. psz4
  551. ));
  552. // jarbats
  553. // sierra's setup faults overwriting video/sound buffer
  554. // limits. by returning videospeed as non-existent
  555. // we force it to use the default videospeed path,not the optimized
  556. // "bad" path code.
  557. // this is matching with setup.exe in the registry which is not specific
  558. // enough. post-beta2 enhance matching process to match version resources
  559. if( (CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_SAYITSNOTTHERE) &&
  560. !WOW32_stricmp(psz4, "sierra.ini") &&
  561. !WOW32_stricmp(psz1, "Config") &&
  562. !WOW32_stricmp(psz2, "VideoSpeed")
  563. ) {
  564. ul = parg16->f3;
  565. }
  566. FREEPSZPTR(psz1);
  567. FREEPSZPTR(psz2);
  568. FREEPSZPTR(psz4);
  569. FREEARGPTR(parg16);
  570. RETURN(ul);
  571. }
  572. ULONG FASTCALL WK32GetModuleFileName(PVDMFRAME pFrame)
  573. {
  574. ULONG ul;
  575. PSZ psz2;
  576. register PGETMODULEFILENAME16 parg16;
  577. HANDLE hT;
  578. GETARGPTR(pFrame, sizeof(GETMODULEFILENAME16), parg16);
  579. ALLOCVDMPTR(parg16->f2, parg16->f3, psz2);
  580. //
  581. // ShellExecute DDE returns (HINST)33 when DDE is used
  582. // to satisfy a request. This looks like a task alias
  583. // to ISTASKALIAS but it's not.
  584. //
  585. if ( ISTASKALIAS(parg16->f1) && 33 != parg16->f1) {
  586. ul = GetHtaskAliasProcessName(parg16->f1,psz2,INT32(parg16->f3));
  587. } else {
  588. hT = (parg16->f1 && (33 != parg16->f1))
  589. ? (HMODULE32(parg16->f1))
  590. : GetModuleHandle(NULL) ;
  591. ul = GETINT16(GetModuleFileName(hT, psz2, INT32(parg16->f3)));
  592. }
  593. FLUSHVDMPTR(parg16->f2, strlen(psz2)+1, psz2);
  594. FREEVDMPTR(psz2);
  595. FREEARGPTR(parg16);
  596. RETURN(ul);
  597. }
  598. ULONG FASTCALL WK32WOWFreeResource(PVDMFRAME pFrame)
  599. {
  600. ULONG ul;
  601. register PWOWFREERESOURCE16 parg16;
  602. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  603. ul = GETBOOL16(FreeResource(
  604. HCURSOR32(parg16->f1)
  605. ));
  606. FREEARGPTR(parg16);
  607. RETURN(ul);
  608. }
  609. ULONG FASTCALL WK32GetDriveType(PVDMFRAME pFrame)
  610. {
  611. ULONG ul;
  612. CHAR RootPathName[] = "?:\\";
  613. register PGETDRIVETYPE16 parg16;
  614. GETARGPTR(pFrame, sizeof(GETDRIVETYPE16), parg16);
  615. // Form Root path
  616. RootPathName[0] = (CHAR)('A'+ parg16->f1);
  617. ul = GetDriveType (RootPathName);
  618. // bugbug - temporariy fixed, should be removed when base changes
  619. // its return value for non-exist drives
  620. // Windows 3.0 sdk manaul said this api should return 1
  621. // if the drive doesn't exist. Windows 3.1 sdk manual said
  622. // this api should return 0 if it failed. Windows 3.1 winfile.exe
  623. // expects 0 for noexisting drives. The NT WIN32 API uses
  624. // 3.0 convention. Therefore, we reset the value to zero
  625. // if it is 1.
  626. if (ul <= 1)
  627. ul = 0;
  628. // DRIVE_CDROM and DRIVE_RAMDISK are not supported under Win 3.1
  629. if ( ul == DRIVE_CDROM ) {
  630. ul = DRIVE_REMOTE;
  631. }
  632. if ( ul == DRIVE_RAMDISK ) {
  633. ul = DRIVE_FIXED;
  634. }
  635. FREEARGPTR(parg16);
  636. RETURN(ul);
  637. }
  638. /* WK32TermsrvGetWindowsDir - Front end to TermsrvGetWindowDirectory.
  639. *
  640. *
  641. * Entry - pszPath - Pointer to return buffer for path (ascii)
  642. * usPathLen - Size of path buffer (bytes)
  643. *
  644. * Exit
  645. * SUCCESS
  646. * True
  647. *
  648. * FAILURE
  649. * False
  650. *
  651. */
  652. ULONG FASTCALL WK32TermsrvGetWindowsDir(PVDMFRAME pFrame)
  653. {
  654. PTERMSRVGETWINDIR16 parg16;
  655. PSTR psz;
  656. NTSTATUS Status = 0;
  657. USHORT usPathLen;
  658. //
  659. // Get arguments.
  660. //
  661. GETARGPTR(pFrame, sizeof(TERMSRVGETWINDIR16), parg16);
  662. psz = SEGPTR(FETCHWORD(parg16->pszPathSegment),
  663. FETCHWORD(parg16->pszPathOffset));
  664. usPathLen = FETCHWORD(parg16->usPathLen);
  665. FREEARGPTR(parg16);
  666. Status = GetWindowsDirectoryA(psz, usPathLen);
  667. // If this is a long path name then get the short one
  668. // Otherwise it will return the same path
  669. GetShortPathNameA(psz, psz, (DWORD)Status);
  670. // Get the real size.
  671. Status = lstrlen(psz);
  672. return(NT_SUCCESS(Status));
  673. }