|
|
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
mapembed.c
Abstract:
This module contains the functions that perform the mapping between the "embedding" section of win.ini, and the subkeys of HKEY_CLASSES_ROOT.
This mapping is a hack implemented on Win3.1, that must also exist on NT. It is implemnted in the WOW layer, since only some win16 apps that read or write to the "embedding" section ( WinWord and MsMail) depend on it.
Author:
Jaime F. Sasson (jaimes) 25-Nov-1992
--*/
#include "precomp.h"
#pragma hdrstop
MODNAME(mapembed.c);
#define WININITIMEOUT 2000
#define BUFFER_SIZE 128
#define EMPTY_STRING ""
DWORD _LastTimeUpdated = 0;
BOOL IsWinIniHelper( IN LPSTR FileName )
/*++
Routine Description:
Determine if the name passed as argument refers to the file win.ini. Used by IS_WIN_INI macro, which assures the argument is non-null and deals with exact match of "win.ini".
Arguments:
FileName - File name to be examined.
Return Value:
BOOL - Returns TRUE if 'Name' refers to win.ini. Otherwise, returns FALSE.
--*/
{ CHAR BufferForFullPath[MAX_PATH]; PSTR PointerToName; DWORD SizeOfFullPath;
BOOL Result;
#ifdef DEBUG
//
// Filename argument must already be lowercase. Be sure.
//
{ char Lowercase[MAX_PATH];
WOW32ASSERT(strlen(FileName) < MAX_PATH-1); strcpy(Lowercase, FileName); WOW32_strlwr(Lowercase); WOW32ASSERT(!WOW32_strcmp(FileName, Lowercase)); } #endif
if (!WOW32_strcmp(FileName, szWinDotIni)) { Result = TRUE; goto Done; }
SizeOfFullPath = GetFullPathName( FileName, sizeof BufferForFullPath, BufferForFullPath, &PointerToName );
if (SizeOfFullPath == 0) { Result = FALSE; goto Done; }
WOW32ASSERT( (SizeOfFullPath + 1) <= sizeof BufferForFullPath );
WOW32ASSERTMSG(pszWinIniFullPath && pszWinIniFullPath[0], "WOW32 ERROR pszWinIniFullPath not initialized.\n");
Result = !WOW32_stricmp( pszWinIniFullPath, BufferForFullPath );
Done: return Result; }
VOID UpdateEmbeddingAllKeys( )
/*++
Routine Description:
Update the "embedding" section of win.ini based on the information stored on the subkeys of HKEY_CLASSES_ROOT.
Arguments:
None.
Return Value:
None.
--*/
{ LONG iClass; CHAR szClass[MAX_PATH + 1]; LONG Status;
for (iClass = 0; (Status = RegEnumKey(HKEY_CLASSES_ROOT,iClass,szClass,sizeof( szClass ))) != ERROR_NO_MORE_ITEMS; iClass++) { if( Status == ERROR_SUCCESS ) { UpdateEmbeddingKey( szClass ); } } }
VOID UpdateEmbeddingKey( IN LPSTR KeyName )
/*++
Routine Description:
Update one key of the "embedding" section of win.ini based on the information stored on the correspondent subkey of HKEY_CLASSES_ROOT.
The code below is an improved version of the function "UpdateWinIni" extracted from Win 3.1 (shell\library\dbf.c).
Arguments:
KeyName - Name of the key to be updated.
Return Value:
None.
--*/
{ LONG Status; HKEY Key; PSTR szClass;
LPSTR szClassName; CHAR BufferForClassName[BUFFER_SIZE]; // char szClassName[60];
LPSTR szServer; CHAR BufferForServer[BUFFER_SIZE]; // char szServer[64];
LPSTR szLine; CHAR BufferForLine[2*BUFFER_SIZE]; // char szLine[128];
char szOldLine[2*BUFFER_SIZE]; // char szOldLine[128];
LPSTR lpDesc, lpForms; int nCommas;
LONG cchClassNameSize; LONG cchServerSize; LONG cchLineSize;
if( KeyName == NULL ) { return; }
szClass = KeyName; Key = NULL;
szClassName = BufferForClassName; cchClassNameSize = sizeof( BufferForClassName );
szServer = BufferForServer; cchServerSize = sizeof( BufferForServer );
szLine = BufferForLine;
if( RegOpenKey( HKEY_CLASSES_ROOT, szClass, &Key ) != ERROR_SUCCESS ) goto NukeClass;
Status = RegQueryValue(Key,NULL,szClassName,&cchClassNameSize); if( ( Status != ERROR_SUCCESS ) && ( Status != ERROR_MORE_DATA ) ) goto NukeClass;
if( Status == ERROR_MORE_DATA ) { cchClassNameSize++; szClassName = ( PSTR )malloc_w( cchClassNameSize ); if( szClassName == NULL ) goto NukeClass;
Status = RegQueryValue(Key,NULL,szClassName,&cchClassNameSize); if( Status != ERROR_SUCCESS ) goto NukeClass; }
if (!*szClassName) goto NukeClass;
Status = RegQueryValue(Key,szServerKey,szServer,&cchServerSize); if( ( Status != ERROR_SUCCESS ) && ( Status != ERROR_MORE_DATA ) ) goto NukeClass;
if( Status == ERROR_MORE_DATA ) { cchServerSize++; szServer = malloc_w( cchServerSize ); if( szServer == NULL ) goto NukeClass;
Status = RegQueryValue(Key,szServerKey,szServer,&cchServerSize); if( Status != ERROR_SUCCESS ) goto NukeClass; }
if (!*szServer) goto NukeClass;
if (GetProfileString(szEmbedding, szClass, EMPTY_STRING, szOldLine, sizeof(szOldLine))) { for (lpForms=szOldLine, nCommas=0; ; lpForms=AnsiNext(lpForms)) { while (*lpForms == ',') { *lpForms++ = '\0'; if (++nCommas == 3) goto FoundForms; } if (!*lpForms) goto DoDefaults; } FoundForms: lpDesc = szOldLine; } else { DoDefaults: lpDesc = szClassName; lpForms = szPicture; }
// we have a class, a classname, and a server, so its an le class
cchLineSize = strlen( lpDesc ) + strlen( szClassName ) + strlen( szServer ) + strlen( lpForms ) + 3 + 1;
if( cchLineSize > sizeof( BufferForLine ) ) { szLine = malloc_w( cchLineSize ); if( szLine == NULL ) goto NukeClass; } wsprintf(szLine, "%s,%s,%s,%s", lpDesc, (LPSTR)szClassName, (LPSTR)szServer, lpForms);
WriteProfileString(szEmbedding, szClass, szLine); if( Key != NULL ) { RegCloseKey( Key ); } if( szClassName != BufferForClassName ) { free_w( szClassName ); } if( szServer != BufferForServer ) { free_w( szServer ); } if( szLine != BufferForLine ) { free_w( szLine ); } return;
NukeClass: /*
Don't nuke the class because someone else may use it!
*/ if( Key != NULL ) { RegCloseKey( Key ); } if( szClassName != BufferForClassName ) { free_w( szClassName ); } if( szServer != BufferForServer ) { free_w( szServer ); } if( szLine != BufferForLine ) { free_w( szLine ); } WriteProfileString(szEmbedding,szClass,NULL); }
VOID UpdateClassesRootSubKey( IN LPSTR KeyName, IN LPSTR Value )
/*++
Routine Description:
Update a subkeys of HKEY_CLASSES_ROOT, based on the corresponding key in the "embedding" section of win.ini.
The code below is an improved version of the function "UpdateFromWinIni" extracted from Win 3.1 (shell\library\dbf.c).
Arguments:
KeyName - Name of the subkey to be updated
Value - The value associated to the key, that was already written to the "embedding" section of win.ini.
Return Value:
None.
--*/
{ LPSTR szLine; LPSTR lpClass,lpServer,lpClassName; LPSTR lpT; HKEY key = NULL; HKEY key1 = NULL;
if( ( KeyName == NULL ) || ( Value == NULL ) ) { return; }
lpClass = KeyName; szLine = Value;
if (!(lpClassName=WOW32_strchr(szLine, ','))) return; // get the server name and null terminate the class name
if (!(lpServer=WOW32_strchr(++lpClassName, ','))) { return; } *lpServer++ = '\0';
// null terminate the server
if (!(lpT=WOW32_strchr(lpServer, ','))) { return; } *lpT++ = '\0';
// make sure the classname is nonblank
while (*lpClassName == ' ') lpClassName++; if (!*lpClassName) return;
// make sure the server name is nonblank
while (*lpServer == ' ') lpServer++; if (!*lpServer) return;
// we now have a valid entry
key = NULL; if( ( RegCreateKey( HKEY_CLASSES_ROOT, lpClass, &key ) != ERROR_SUCCESS ) || ( RegSetValue( key, NULL, REG_SZ, lpClassName, strlen( lpClassName ) ) != ERROR_SUCCESS ) ) { if( key != NULL ) { RegCloseKey( key ); } return; } if( ( RegCreateKey( key, szServerKey, &key1 ) != ERROR_SUCCESS ) || ( RegSetValue( key1, NULL, REG_SZ, lpServer, strlen( lpServer ) ) != ERROR_SUCCESS ) ) { if( key != NULL ) { RegCloseKey( key ); } if( key1 != NULL ) { RegCloseKey( key1 ); } return; } RegCloseKey( key ); RegCloseKey( key1 ); }
VOID SetLastTimeUpdated( )
/*++
Routine Description:
Set the variable that contains the information of when the "embedding" section of win.ini was last updated.
Arguments:
None.
Return Value:
None.
--*/
{ _LastTimeUpdated = GetTickCount(); }
BOOL WasSectionRecentlyUpdated( )
/*++
Routine Description:
Inform the caller whether the "embedding" section of win.ini was recently updated ( less than 2 seconds ).
Arguments:
None.
Return Value:
BOOLEAN - Returns TRUE if the "embedding" section was updated less than 2 seconds ago.
--*/
{ DWORD Now;
Now = GetTickCount(); return( ( ( Now - _LastTimeUpdated ) < WININITIMEOUT ) ? TRUE : FALSE ); }
|