504 lines
9.9 KiB
C
504 lines
9.9 KiB
C
/*++
|
||
|
||
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 );
|
||
}
|