|
|
/*++
* * WOW v1.0 * * Copyright (c) 1991, Microsoft Corporation * * WKERNEL.C * WOW32 16-bit Kernel API support * * History: * Created 07-Mar-1991 by Jeff Parsons (jeffpar) --*/
#include "precomp.h"
#pragma hdrstop
MODNAME(wkernel.c);
ULONG FASTCALL WK32WritePrivateProfileString(PVDMFRAME pFrame) { ULONG ul; PSZ pszSection; PSZ pszKey; PSZ pszValue; PSZ pszFilename; register PWRITEPRIVATEPROFILESTRING16 parg16; BOOL fIsWinIni; CHAR szLowercase[MAX_PATH];
GETARGPTR(pFrame, sizeof(WRITEPRIVATEPROFILESTRING16), parg16); GETPSZPTR(parg16->f1, pszSection); GETPSZPTR(parg16->f2, pszKey); GETPSZPTR(parg16->f3, pszValue); GETPSZPTR(parg16->f4, pszFilename);
UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
strcpy(szLowercase, pszFilename); WOW32_strlwr(szLowercase);
fIsWinIni = IS_WIN_INI(szLowercase);
// Trying to install or change default printer to fax printer?
if (fIsWinIni && pszSection && pszKey && pszValue && !WOW32_stricmp(pszSection, szDevices) && IsFaxPrinterWriteProfileString(pszSection, pszKey, pszValue)) {
ul = TRUE; goto Done; }
ul = GETBOOL16( WritePrivateProfileString( pszSection, pszKey, pszValue, pszFilename ));
if( ul != 0 && fIsWinIni && IS_EMBEDDING_SECTION( pszSection ) && pszKey != NULL && pszValue != NULL ) {
UpdateClassesRootSubKey( pszKey, pszValue); }
Done: FREEPSZPTR(pszSection); FREEPSZPTR(pszKey); FREEPSZPTR(pszValue); FREEPSZPTR(pszFilename); FREEARGPTR(parg16);
return ul; }
ULONG FASTCALL WK32WriteProfileString(PVDMFRAME pFrame) { ULONG ul; PSZ pszSection; PSZ pszKey; PSZ pszValue; register PWRITEPROFILESTRING16 parg16;
GETARGPTR(pFrame, sizeof(WRITEPROFILESTRING16), parg16); GETPSZPTR(parg16->f1, pszSection); GETPSZPTR(parg16->f2, pszKey); GETPSZPTR(parg16->f3, pszValue);
// For WinFax Lite install hack. Bug #126489 See wow32fax.c
if(!gbWinFaxHack) {
// Trying to install or change default printer to fax printer?
if (pszSection && pszKey && pszValue && !WOW32_stricmp(pszSection, szDevices) && IsFaxPrinterWriteProfileString(pszSection, pszKey, pszValue)) { ul = TRUE; goto Done; } } else { IsFaxPrinterWriteProfileString(pszSection, pszKey, pszValue); }
ul = GETBOOL16( WriteProfileString( pszSection, pszKey, pszValue ));
if( ( ul != 0 ) && IS_EMBEDDING_SECTION( pszSection ) && ( pszKey != NULL ) && ( pszValue != NULL ) ) { UpdateClassesRootSubKey( pszKey, pszValue); }
Done: FREEPSZPTR(pszSection); FREEPSZPTR(pszKey); FREEPSZPTR(pszValue); FREEARGPTR(parg16); return ul; }
ULONG FASTCALL WK32GetProfileString(PVDMFRAME pFrame) { ULONG ul; PSZ pszSection; PSZ pszKey; PSZ pszDefault; PSZ pszReturnBuffer; UINT cchMax; #ifdef FE_SB
PSZ pszTmp = NULL; #endif // FE_SB
register PGETPROFILESTRING16 parg16;
GETARGPTR(pFrame, sizeof(GETPROFILESTRING16), parg16); GETPSZPTR(parg16->f1, pszSection); GETPSZPTR(parg16->f2, pszKey); GETPSZPTR(parg16->f3, pszDefault); ALLOCVDMPTR(parg16->f4, parg16->f5, pszReturnBuffer); cchMax = INT32(parg16->f5); #ifdef FE_SB
//
// For those applications that expect sLongDate contains
// windows 3.1J picture format string.
//
if (GetSystemDefaultLangID() == 0x411 && !lstrcmpi(pszSection, "intl") && !lstrcmpi(pszKey, "sLongDate")) {
pszTmp = pszKey; pszKey = "sLongDate16"; } #endif // FE_SB
if (IS_EMBEDDING_SECTION( pszSection ) && !WasSectionRecentlyUpdated() ) { if( pszKey == NULL ) { UpdateEmbeddingAllKeys(); } else { UpdateEmbeddingKey( pszKey ); } SetLastTimeUpdated();
} else if (pszSection && pszKey && !WOW32_stricmp(pszSection, szDevices) && IsFaxPrinterSupportedDevice(pszKey)) {
ul = GETINT16(GetFaxPrinterProfileString(pszSection, pszKey, pszDefault, pszReturnBuffer, cchMax)); goto FlushAndReturn; }
ul = GETINT16(GetProfileString( pszSection, pszKey, pszDefault, pszReturnBuffer, cchMax));
//
// Win3.1/Win95 compatibility: Zap the first trailing blank in pszDefault
// with null, but only if the default string was returned. To detect
// the default string being returned we need to ignore trailing blanks.
//
// This code is duplicated in thunks for GetProfileString and
// GetPrivateProfileString, update both if you make changes.
//
if ( pszDefault && pszKey ) {
int n, nLenDef;
//
// Is the default the same as the returned string up to any NULLs?
//
nLenDef = 0; n=0; while ( (pszDefault[nLenDef] == pszReturnBuffer[n]) && pszReturnBuffer[n] ) { n++; nLenDef++; } //
// Did we get out of the loop because we're at the end of the returned string?
//
if ( '\0' != pszReturnBuffer[n] ) { //
// No. The strings are materially different - fall out.
//
} else { //
// Ok, the strings are identical to the end of the returned string.
// Is the default string spaces out to the end?
//
while ( ' ' == pszDefault[nLenDef] ) { nLenDef++; } //
// The last thing was not a space. If it was a NULL, then the app
// passed in a string with trailing NULLs as default. (Otherwise
// the two strings are materially different and we do nothing.)
//
if ( '\0' == pszDefault[nLenDef] ) { char szBuf[4]; // Some random, small number of chars to get.
// If the string is long, we'll get only 3 chars
// (and NULL), but so what? - we only need to know if
// we got a default last time...
//
// The returned string is the same as the default string
// without trailing blanks, but this might be coincidence,
// so see if a call with empty pszDefault returns anything.
// If it does, we don't zap because the default isn't
// being used.
//
if (0 == GetProfileString(pszSection, pszKey, "", szBuf, sizeof(szBuf))) {
//
// Zap first trailing blank in pszDefault with null.
//
pszDefault[ul] = 0; FLUSHVDMPTR(parg16->f3 + ul, 1, pszDefault + ul); } } } }
FlushAndReturn: #ifdef FE_SB
if ( pszTmp ) pszKey = pszTmp;
if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_USEUPPER) { // for WinWrite
if (pszSection && !lstrcmpi(pszSection, "windows") && pszKey && !lstrcmpi(pszKey, "device")) { CharUpper(pszReturnBuffer); } if (pszSection && !lstrcmpi(pszSection, "devices") && pszKey) { CharUpper(pszReturnBuffer); } } #endif // FE_SB
FLUSHVDMPTR(parg16->f4, (ul + (pszSection && pszKey) ? 1 : 2), pszReturnBuffer); FREEPSZPTR(pszSection); FREEPSZPTR(pszKey); FREEPSZPTR(pszDefault); FREEVDMPTR(pszReturnBuffer); FREEARGPTR(parg16); RETURN(ul); }
ULONG FASTCALL WK32GetPrivateProfileString(PVDMFRAME pFrame) { ULONG ul; PSZ pszSection; PSZ pszKey; PSZ pszDefault; PSZ pszReturnBuffer; PSZ pszFilename; UINT cchMax; #ifdef FE_SB
PSZ pszTmp = NULL; #endif // FE_SB
register PGETPRIVATEPROFILESTRING16 parg16; CHAR szLowercase[MAX_PATH];
GETARGPTR(pFrame, sizeof(GETPRIVATEPROFILESTRING16), parg16); GETPSZPTR(parg16->f1, pszSection); GETPSZPTR(parg16->f2, pszKey); GETPSZPTR(parg16->f3, pszDefault); ALLOCVDMPTR(parg16->f4, parg16->f5, pszReturnBuffer); GETPSZPTR(parg16->f6, pszFilename);
// PC3270 (Personal communications): while installing this app it calls
// GetPrivateProfileString (sectionname, NULL, defaultbuffer, returnbuffer,
// cch = 0, filename). On win31 this call returns relevant data in return
// buffer and corresponding size as return value. On NT, since the
// buffersize(cch) is '0' no data is copied into the return buffer and
// return value is zero which makes this app abort installation.
//
// So restricted compatibility:
// if above is the case set
// cch = 64k - offset of returnbuffer;
//
// A safer 'cch' would be
// cch = GlobalSize(selector of returnbuffer) -
// (offset of returnbuffer);
// - nanduri
if (!(cchMax = INT32(parg16->f5))) { if (pszKey == (PSZ)NULL) { if (pszReturnBuffer != (PSZ)NULL) { cchMax = 0xffff - (LOW16(parg16->f4)); } } }
UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
strcpy(szLowercase, pszFilename); WOW32_strlwr(szLowercase);
if (IS_WIN_INI( szLowercase )) { #ifdef FE_SB
//
// For those applications that expect sLongDate contains
// windows 3.1J picture format string.
//
if (GetSystemDefaultLangID() == 0x411 && lstrcmpi( pszSection, "intl") == 0 && lstrcmpi( pszKey, "sLongDate") == 0) { pszTmp = pszKey; pszKey = "sLongDate16"; } #endif // FE_SB
if (IS_EMBEDDING_SECTION( pszSection ) && !WasSectionRecentlyUpdated() ) { if( pszKey == NULL ) { UpdateEmbeddingAllKeys(); } else { UpdateEmbeddingKey( pszKey ); } SetLastTimeUpdated();
} else if (pszSection && pszKey && !WOW32_stricmp(pszSection, szDevices) && IsFaxPrinterSupportedDevice(pszKey)) {
ul = GETINT16(GetFaxPrinterProfileString(pszSection, pszKey, pszDefault, pszReturnBuffer, cchMax)); goto FlushAndReturn; } }
ul = GETUINT16(GetPrivateProfileString( pszSection, pszKey, pszDefault, pszReturnBuffer, cchMax, pszFilename));
// start comaptibility hacks
//
// Win3.1/Win95 compatibility: Zap the first trailing blank in pszDefault
// with null, but only if the default string was returned. To detect
// the default string being returned we need to ignore trailing blanks.
//
// This code is duplicated in thunks for GetProfileString and
// GetPrivateProfileString, update both if you make changes.
//
if ( pszDefault && pszKey ) {
int n, nLenDef;
//
// Is the default the same as the returned string up to any NULLs?
//
nLenDef = 0; n=0; while ( (pszDefault[nLenDef] == pszReturnBuffer[n]) && pszReturnBuffer[n] ) { n++; nLenDef++; } //
// Did we get out of the loop because we're at the end of the returned string?
//
if ( '\0' != pszReturnBuffer[n] ) { //
// No. The strings are materially different - fall out.
//
} else { //
// Ok, the strings are identical to the end of the returned string.
// Is the default string spaces out to the end?
//
while ( ' ' == pszDefault[nLenDef] ) { nLenDef++; } //
// The last thing was not a space. If it was a NULL, then the app
// passed in a string with trailing NULLs as default. (Otherwise
// the two strings are materially different and we do nothing.)
//
if ( '\0' == pszDefault[nLenDef] ) { char szBuf[4]; // Some random, small number of chars to get.
// If the string is long, we'll get only 3 chars
// (and NULL), but so what? - we only need to know if
// we got a default last time...
//
// The returned string is the same as the default string
// without trailing blanks, but this might be coincidence,
// so see if a call with empty pszDefault returns anything.
// If it does, we don't zap because the default isn't
// being used.
//
if (0 == GetProfileString(pszSection, pszKey, "", szBuf, sizeof(szBuf))) {
//
// Zap first trailing blank in pszDefault with null.
//
pszDefault[ul] = 0; FLUSHVDMPTR(parg16->f3 + ul, 1, pszDefault + ul); } } } }
if( CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_SAYITSNOTTHERE ) { // CrossTalk 2.2 gets hung in a loop while trying to match a printer in
// their xtalk.ini file with a printer name in the PrintDlg listbox.
// There is a bug in their code for handling this that gets exposed by
// the fact that NT PrintDlg listboxes do not include the port name as
// Win3.1 & Win'95 do. We avoid the buggy code altogether with this
// hack by telling them that the preferred printer isn't stored in
// xtalk.ini. See bug #43168 a-craigj
// Maximizer 5.0 has similar problem. it tries to parse
// print driver location however, allocates too small buffer. See
// Whistler bug 288491
if(!WOW32_stricmp(pszSection, "Printer")) { if((WOW32_strstr(szLowercase, "xtalk.ini") && !WOW32_stricmp(pszKey, "Device")) || // CrossTalk 2.2
(WOW32_strstr(szLowercase, "bclwdde.ini") && !WOW32_stricmp(pszKey, "Driver")) ){ // Maximizer 5
strcpy(pszReturnBuffer, pszDefault); ul = strlen(pszReturnBuffer); } }
// WHISTLER RAID BUG # 379253 05/06/2001 - alexsm
// National Geographic Explorer needed the oppisite of the above. The app
// was checking for a QTWVideo string, which contained a path to a quicktime
// driver. Without the key, the app wouldn't play video. It's not really a
// SAYITSNOTTHERE, more of a SAYITISTHERE, but this saves on compat bits.
if(!WOW32_stricmp(pszSection, "mci")) { if((WOW32_strstr(szLowercase, "system.ini") && !WOW32_stricmp(pszKey, "QTWVideo"))) { CHAR szMCIQTW[] = "\\system\\mciqtw.drv"; CHAR szQTWVideo[MAX_PATH + sizeof(szMCIQTW) / sizeof(CHAR)]; // make sure there's room for the new string (max_path + pszMCIQTW)
GetSystemWindowsDirectory(szQTWVideo, MAX_PATH); strcat(szQTWVideo, szMCIQTW); strncpy(pszReturnBuffer, szQTWVideo, cchMax - 1); *(pszReturnBuffer + (cchMax - 1)) = '\0'; ul = strlen(szQTWVideo); } }
}
FlushAndReturn: #ifdef FE_SB
if ( pszTmp ) pszKey = pszTmp; #endif // FE_SB
if (ul) { FLUSHVDMPTR(parg16->f4, (ul + (pszSection && pszKey) ? 1 : 2), pszReturnBuffer); LOGDEBUG(8,("GetPrivateProfileString returns '%s'\n", pszReturnBuffer)); }
#ifdef DEBUG
//
// Check for bad return on retrieving entire section by walking
// the section making sure it's full of null-terminated strings
// with an extra null at the end. Also ensure that this all fits
// within the buffer.
//
if (!pszKey) { PSZ psz;
//
// We don't want to complain if the poorly-formed buffer was the one
// passed in as pszDefault by the caller.
//
// Although the api docs clearly state that pszDefault should never
// be null but win3.1 is nice enough to still deal with this. Delphi is
// passing pszDefault as NULL and this following code causes an
// assertion in WOW. So added the pszDefault check first.
//
// sudeepb 11-Sep-1995
if (!pszDefault || WOW32_strcmp(pszReturnBuffer, pszDefault)) {
psz = pszReturnBuffer;
while (psz < (pszReturnBuffer + ul + 2) && *psz) { psz += strlen(psz) + 1; }
WOW32ASSERTMSGF( psz < (pszReturnBuffer + ul + 2), ("GetPrivateProfileString of entire section returns poorly formed buffer.\n" "pszReturnBuffer = %p, return value = %d\n", pszReturnBuffer, ul )); } }
#endif // DEBUG
FREEPSZPTR(pszSection); FREEPSZPTR(pszKey); FREEPSZPTR(pszDefault); FREEVDMPTR(pszReturnBuffer); FREEPSZPTR(pszFilename); FREEARGPTR(parg16); RETURN(ul); }
ULONG FASTCALL WK32GetProfileInt(PVDMFRAME pFrame) { ULONG ul; PSZ psz1; PSZ psz2; register PGETPROFILEINT16 parg16;
GETARGPTR(pFrame, sizeof(GETPROFILEINT16), parg16); GETPSZPTR(parg16->f1, psz1); GETPSZPTR(parg16->f2, psz2);
ul = GETWORD16(GetProfileInt( psz1, psz2, INT32(parg16->f3) ));
//
// In HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics, there
// are a bunch of values that define the screen appearance. You can
// watch these values get updated when you go into the display control
// panel applet and change the "appearance scheme", or any of the
// individual elements. The win95 shell is different than win31 in that it
// sticks "twips" values in there instead of pixels. These are calculated
// with the following formula:
//
// twips = - pixels * 72 * 20 / cyPixelsPerInch
//
// pixels = -twips * cyPixelsPerInch / (72*20)
//
// So if the value is negative, it is in twips, otherwise it in pixels.
// The idea is that these values are device independent. NT is
// different than win95 in that we provide an Ini file mapping to this
// section of the registry where win95 does not. Now, when the Lotus
// Freelance Graphics 2.1 tutorial runs, it mucks around with the look
// of the screen, and it changes the border width of window frames by
// using SystemParametersInfo(). When it tries to restore it, it uses
// GetProfileInt("Windows", "BorderWidth", <default>), which on win31
// returns pixels, on win95 returns the default (no ini mapping), and
// on NT returns TWIPS. Since this negative number is interpreted as
// a huge UINT, then the window frames become huge. What this code
// below will do is translate the number back to pixels. [neilsa]
//
if ((CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_PIXELMETRICS) && !WOW32_stricmp(psz1, "Windows") && !WOW32_stricmp(psz2, "BorderWidth") && ((INT)ul < 0)) {
HDC hDC = CreateDC("DISPLAY", NULL, NULL, NULL); if ( !hDC ) { ul = (ULONG) (-(INT)ul * GetDeviceCaps(hDC, LOGPIXELSY)/(72*20)); DeleteDC(hDC); } }
FREEPSZPTR(psz1); FREEPSZPTR(psz2); FREEARGPTR(parg16); RETURN(ul); }
ULONG FASTCALL WK32GetPrivateProfileInt(PVDMFRAME pFrame) { ULONG ul; PSZ psz1; PSZ psz2; PSZ psz4; register PGETPRIVATEPROFILEINT16 parg16;
GETARGPTR(pFrame, sizeof(GETPRIVATEPROFILEINT16), parg16); GETPSZPTR(parg16->f1, psz1); GETPSZPTR(parg16->f2, psz2); GETPSZPTR(parg16->f4, psz4);
UpdateDosCurrentDirectory(DIR_DOS_TO_NT); ul = GETWORD16(GetPrivateProfileInt( psz1, psz2, INT32(parg16->f3), psz4 ));
// jarbats
// sierra's setup faults overwriting video/sound buffer
// limits. by returning videospeed as non-existent
// we force it to use the default videospeed path,not the optimized
// "bad" path code.
// this is matching with setup.exe in the registry which is not specific
// enough. post-beta2 enhance matching process to match version resources
if( (CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_SAYITSNOTTHERE) && !WOW32_stricmp(psz4, "sierra.ini") && !WOW32_stricmp(psz1, "Config") && !WOW32_stricmp(psz2, "VideoSpeed") ) { ul = parg16->f3; }
FREEPSZPTR(psz1); FREEPSZPTR(psz2); FREEPSZPTR(psz4); FREEARGPTR(parg16); RETURN(ul); }
ULONG FASTCALL WK32GetModuleFileName(PVDMFRAME pFrame) { ULONG ul; PSZ psz2; register PGETMODULEFILENAME16 parg16; HANDLE hT;
GETARGPTR(pFrame, sizeof(GETMODULEFILENAME16), parg16); ALLOCVDMPTR(parg16->f2, parg16->f3, psz2); //
// ShellExecute DDE returns (HINST)33 when DDE is used
// to satisfy a request. This looks like a task alias
// to ISTASKALIAS but it's not.
//
if ( ISTASKALIAS(parg16->f1) && 33 != parg16->f1) { ul = GetHtaskAliasProcessName(parg16->f1,psz2,INT32(parg16->f3)); } else { hT = (parg16->f1 && (33 != parg16->f1)) ? (HMODULE32(parg16->f1)) : GetModuleHandle(NULL) ; ul = GETINT16(GetModuleFileName(hT, psz2, INT32(parg16->f3))); }
FLUSHVDMPTR(parg16->f2, strlen(psz2)+1, psz2); FREEVDMPTR(psz2); FREEARGPTR(parg16); RETURN(ul); }
ULONG FASTCALL WK32WOWFreeResource(PVDMFRAME pFrame) { ULONG ul; register PWOWFREERESOURCE16 parg16;
GETARGPTR(pFrame, sizeof(*parg16), parg16);
ul = GETBOOL16(FreeResource( HCURSOR32(parg16->f1) ));
FREEARGPTR(parg16); RETURN(ul); }
ULONG FASTCALL WK32GetDriveType(PVDMFRAME pFrame) { ULONG ul; CHAR RootPathName[] = "?:\\"; register PGETDRIVETYPE16 parg16;
GETARGPTR(pFrame, sizeof(GETDRIVETYPE16), parg16);
// Form Root path
RootPathName[0] = (CHAR)('A'+ parg16->f1);
ul = GetDriveType (RootPathName); // bugbug - temporariy fixed, should be removed when base changes
// its return value for non-exist drives
// Windows 3.0 sdk manaul said this api should return 1
// if the drive doesn't exist. Windows 3.1 sdk manual said
// this api should return 0 if it failed. Windows 3.1 winfile.exe
// expects 0 for noexisting drives. The NT WIN32 API uses
// 3.0 convention. Therefore, we reset the value to zero
// if it is 1.
if (ul <= 1) ul = 0;
// DRIVE_CDROM and DRIVE_RAMDISK are not supported under Win 3.1
if ( ul == DRIVE_CDROM ) { ul = DRIVE_REMOTE; } if ( ul == DRIVE_RAMDISK ) { ul = DRIVE_FIXED; }
FREEARGPTR(parg16); RETURN(ul); }
/* WK32TermsrvGetWindowsDir - Front end to TermsrvGetWindowDirectory.
* * * Entry - pszPath - Pointer to return buffer for path (ascii) * usPathLen - Size of path buffer (bytes) * * Exit * SUCCESS * True * * FAILURE * False * */ ULONG FASTCALL WK32TermsrvGetWindowsDir(PVDMFRAME pFrame) { PTERMSRVGETWINDIR16 parg16; PSTR psz; NTSTATUS Status = 0; USHORT usPathLen;
//
// Get arguments.
//
GETARGPTR(pFrame, sizeof(TERMSRVGETWINDIR16), parg16); psz = SEGPTR(FETCHWORD(parg16->pszPathSegment), FETCHWORD(parg16->pszPathOffset)); usPathLen = FETCHWORD(parg16->usPathLen); FREEARGPTR(parg16);
Status = GetWindowsDirectoryA(psz, usPathLen);
// If this is a long path name then get the short one
// Otherwise it will return the same path
GetShortPathNameA(psz, psz, (DWORD)Status);
// Get the real size.
Status = lstrlen(psz);
return(NT_SUCCESS(Status)); }
|