diff options
Diffstat (limited to 'private/nw/install/setupdll/setvalue.c')
-rw-r--r-- | private/nw/install/setupdll/setvalue.c | 696 |
1 files changed, 696 insertions, 0 deletions
diff --git a/private/nw/install/setupdll/setvalue.c b/private/nw/install/setupdll/setvalue.c new file mode 100644 index 000000000..bfaf073cf --- /dev/null +++ b/private/nw/install/setupdll/setvalue.c @@ -0,0 +1,696 @@ +/**********************************************************************/ +/** Microsoft Windows NT **/ +/** Copyright(c) Microsoft Corp., 1991 **/ +/**********************************************************************/ + +/* + + setvalue.c + Code to enable SetValue for everyone. + + history: + terryk 09/30/93 Created +*/ + + +#if defined(DEBUG) +static const char szFileName[] = __FILE__; +#define _FILENAME_DEFINED_ONCE szFileName +#endif + +#include <string.h> + +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> + +#include <nwlsa.h> +#include <nwapi.h> +#include <nwcfg.h> +#include <nwcfg.hxx> + +extern char achBuff[]; + +// exported functions + +BOOL FAR PASCAL SetFileSysChangeValue( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult ); +BOOL FAR PASCAL SetEverybodyPermission( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult ); +BOOL FAR PASCAL SetupRegistryForNWCS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult ); +BOOL FAR PASCAL SetupRegistryWorker( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult ); +BOOL FAR PASCAL DeleteGatewayPassword( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult ); +BOOL FAR PASCAL CleanupRegistryForNWCS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult ); + +// +// structure for registry munging +// + +typedef struct REG_ENTRY_ { + DWORD Operation ; + LONG Level ; + LPWSTR s1 ; + LPWSTR s2 ; +} REG_ENTRY ; + +// +// local routines +// + +DWORD SetupShellExtensions(REG_ENTRY RegEntries[], DWORD dwNumEntries) ; + +typedef DWORD (*LPNWCLEANUPGATEWAYSHARES)(VOID) ; + +// Values & Tables that define registry data + +#define MAX_REG_LEVEL 10 + +#define CREATE_ABS 1 // create/open a key with absolute path +#define CREATE_REL 2 // create/open a key with relative path +#define VALUE_STR 3 // write a string value +#define DELETE_ABS 4 // delete key with absolute path +#define DELETE_REL 5 // delete key with relative path +#define DELETE_VAL 6 // delete a value +#define DROP_STACK 7 // drop stack by one + +REG_ENTRY RegCreateEntries[] = +{ + {CREATE_ABS,0,L"SOFTWARE\\Classes\\NetWare_or_Compatible_Network", NULL}, + {DELETE_REL,0,L"shellex\\ContextMenuHandlers\\NetWareMenus", NULL}, + {DELETE_REL,0,L"shellex\\ContextMenuHandlers", NULL}, + {DELETE_REL,0,L"shellex\\PropertySheetHandlers\\NetWarePage", NULL}, + {DELETE_REL,0,L"shellex\\PropertySheetHandlers", NULL}, + {DELETE_REL,0,L"shellex", NULL}, + {DROP_STACK,0,NULL,NULL}, + {DELETE_ABS,0,L"SOFTWARE\\Classes\\NetWare_or_Compatible_Network", NULL}, + + {CREATE_ABS, 0,L"SOFTWARE\\Classes\\Network\\Type", NULL}, + {CREATE_REL,+1, L"3", NULL}, + {CREATE_REL,+1, L"shellex", NULL}, + {CREATE_REL,+1, L"ContextMenuHandlers", NULL}, + {CREATE_REL,+1, L"NetWareMenus", NULL}, + {VALUE_STR,0, L"", L"{8e9d6600-f84a-11ce-8daa-00aa004a5691}"}, + {CREATE_REL,-1, L"PropertySheetHandlers", NULL}, + {CREATE_REL,+1, L"NetWarePage", NULL}, + {VALUE_STR,0, L"", L"{8e9d6600-f84a-11ce-8daa-00aa004a5691}"}, + {CREATE_ABS, 0,L"SOFTWARE\\Classes\\CLSID", NULL}, + {CREATE_REL,+1, L"{8e9d6600-f84a-11ce-8daa-00aa004a5691}", NULL}, + {VALUE_STR,0, L"", L"NetWare Objects"}, + {CREATE_REL,+1, L"InProcServer32", NULL}, + {VALUE_STR,0, L"", L"nwprovau.dll"}, + {VALUE_STR,0, L"ThreadingModel", L"Apartment"}, + {CREATE_REL,-1, L"{e3f2bac0-099f-11cf-8daa-00aa004a5691}", NULL}, + {VALUE_STR,0, L"", L"NetWare UNC Folder Menu"}, + {CREATE_REL,+1, L"InProcServer32", NULL}, + {VALUE_STR,0, L"", L"nwprovau.dll"}, + {VALUE_STR,0, L"ThreadingModel", L"Apartment"}, + {CREATE_REL,-1, L"{52c68510-09a0-11cf-8daa-00aa004a5691}", NULL}, + {VALUE_STR,0, L"", L"NetWare Hood Verbs"}, + {CREATE_REL,+1, L"InProcServer32", NULL}, + {VALUE_STR,0, L"", L"nwprovau.dll"}, + {VALUE_STR,0, L"ThreadingModel", L"Apartment"}, + {CREATE_REL,-1, L"{208D2C60-3AEA-1069-A2D7-08002B30309D}", NULL}, + {CREATE_REL,+1, L"shellex", NULL}, + {CREATE_REL,+1, L"ContextMenuHandlers", NULL}, + {CREATE_REL,+1, L"NetWareMenus", NULL}, + {VALUE_STR,0, L"", L"{52c68510-09a0-11cf-8daa-00aa004a5691}"}, + {CREATE_ABS, 0,L"SOFTWARE\\Classes\\Folder", NULL}, + {CREATE_REL,+1, L"shellex", NULL}, + {CREATE_REL,+1, L"ContextMenuHandlers", NULL}, + {CREATE_REL,+1, L"NetWareUNCMenu", NULL}, + {VALUE_STR,0, L"", L"{e3f2bac0-099f-11cf-8daa-00aa004a5691}"}, + {CREATE_ABS, 0,L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", NULL}, + {CREATE_REL,+1, L"Shell Extensions", NULL}, + {CREATE_REL,+1, L"Approved", NULL}, + {VALUE_STR,0, L"{8e9d6600-f84a-11ce-8daa-00aa004a5691}", L"Shell extensions for NetWare"}, + {VALUE_STR,0, L"{e3f2bac0-099f-11cf-8daa-00aa004a5691}", L"Shell extensions for NetWare"}, + {VALUE_STR,0, L"{52c68510-09a0-11cf-8daa-00aa004a5691}", L"Shell extensions for NetWare"} +} ; + +REG_ENTRY RegDeleteEntries[] = +{ + {CREATE_ABS,0,L"SOFTWARE\\Classes\\Network\\Type\\3", NULL}, + {DELETE_REL,0,L"shellex\\ContextMenuHandlers\\NetWareMenus", NULL}, + {DELETE_REL,0,L"shellex\\ContextMenuHandlers", NULL}, + {DELETE_REL,0,L"shellex\\PropertySheetHandlers\\NetWarePage", NULL}, + {DELETE_REL,0,L"shellex\\PropertySheetHandlers", NULL}, + {DELETE_REL,0,L"shellex", NULL}, + {DROP_STACK,0,NULL,NULL}, + {DELETE_ABS,0,L"SOFTWARE\\Classes\\Network\\Type\\3", NULL}, + + {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{8e9d6600-f84a-11ce-8daa-00aa004a5691}\\InProcServer32", NULL}, + {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{8e9d6600-f84a-11ce-8daa-00aa004a5691}", NULL}, + {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{e3f2bac0-099f-11cf-8daa-00aa004a5691}\\InProcServer32", NULL}, + {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{e3f2bac0-099f-11cf-8daa-00aa004a5691}", NULL}, + {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{52c68510-09a0-11cf-8daa-00aa004a5691}\\InProcServer32", NULL}, + {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{52c68510-09a0-11cf-8daa-00aa004a5691}", NULL}, + {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{208D2C60-3AEA-1069-A2D7-08002B30309D}\\shellex\\ContextMenuHandlers\\NetWareMenus", NULL}, + + {DELETE_ABS,0,L"SOFTWARE\\Classes\\Folder\\shellex\\ContextMenuHandlers\\NetWareUNCMenu", NULL}, + {CREATE_ABS,0,L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", NULL}, + {DELETE_VAL,0,L"{8e9d6600-f84a-11ce-8daa-00aa004a5691}", NULL}, + {DELETE_VAL,0,L"{e3f2bac0-099f-11cf-8daa-00aa004a5691}", NULL}, + {DELETE_VAL,0,L"{52c68510-09a0-11cf-8daa-00aa004a5691}", NULL} +} ; + + +/******************************************************************* + + NAME: SetEverybodyPermission + + SYNOPSIS: Set the registry key to everybody "Set Value" (or whatever + the caller want.) This is called from the inf file + + ENTRY: Registry key as the first parameter + Permisstion type as the second parameter + + RETURN: BOOL - TRUE for success. + + HISTORY: + terryk 07-May-1993 Created + +********************************************************************/ + +typedef DWORD (*T_SetPermission)(HKEY hKey, DWORD dwPermission); + +BOOL FAR PASCAL SetEverybodyPermission( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult ) +{ + HKEY hKey = (HKEY)atol( &(apszArgs[0][1]) ); // registry key + DWORD dwPermission = atol( apszArgs[1] ); // permission value + DWORD err = ERROR_SUCCESS; + + do { + HINSTANCE hDll = LoadLibraryA( "nwapi32.dll" ); + FARPROC pSetPermission = NULL; + + if ( hDll == NULL ) + { + err = GetLastError(); + break; + } + + pSetPermission = GetProcAddress( hDll, "NwLibSetEverybodyPermission" ); + + if ( pSetPermission == NULL ) + { + err = GetLastError(); + break; + } + err = (*(T_SetPermission)pSetPermission)( hKey, dwPermission ); + } while ( FALSE ); + + wsprintfA( achBuff, "{\"%d\"}", err ); + *ppszResult = achBuff; + + return( err == ERROR_SUCCESS ); +} + +/******************************************************************* + + NAME: SetFileSysChangeValue + + SYNOPSIS: calls common setup routine. this old entry point is + is left here to handle any DLL/INF mismatch. + + ENTRY: NONE from inf file. + + RETURN: BOOL - TRUE for success. + (always return TRUE) + + HISTORY: + chuckc 29-Oct-1993 Created + +********************************************************************/ + +BOOL FAR PASCAL SetFileSysChangeValue( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult ) +{ + return SetupRegistryWorker( nArgs, apszArgs, ppszResult ); +} + +/******************************************************************* + + NAME: SetupRegistryForNWCS + + SYNOPSIS: calls common worker routine to setup registry. + + ENTRY: NONE from inf file. + + RETURN: BOOL - TRUE for success. + (always return TRUE) + + HISTORY: + chuckc 29-Oct-1993 Created + +********************************************************************/ + +BOOL FAR PASCAL SetupRegistryForNWCS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult ) +{ + return SetupRegistryWorker( nArgs, apszArgs, ppszResult ); +} + +/******************************************************************* + + NAME: SetupRegistryWorker + + SYNOPSIS: set the FileSysChangeValue to please NETWARE.DRV. + also set win.ini parameter so wfwnet.drv knows we are there. + + ENTRY: NONE from inf file. + + RETURN: BOOL - TRUE for success. + (always return TRUE) + + HISTORY: + chuckc 29-Oct-1993 Created + +********************************************************************/ + +BOOL FAR PASCAL SetupRegistryWorker( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult ) +{ + DWORD err = 0, err1 = 0 ; + + (void) nArgs ; // quiet the compiler + (void) apszArgs ; // quiet the compiler + + if (!WriteProfileStringA("NWCS", + "NwcsInstalled", + "1")) + { + err = GetLastError() ; + } + + if (!WritePrivateProfileStringA("386Enh", + "FileSysChange", + "off", + "system.ini")) + { + err1 = GetLastError() ; + } + + if (err1 == NO_ERROR) + { + err1 = SetupShellExtensions( + RegCreateEntries, + sizeof(RegCreateEntries)/sizeof(RegCreateEntries[0])) ; + } + + wsprintfA( achBuff, "{\"%d\"}", err ? err : err1 ); + *ppszResult = achBuff; + + return TRUE; +} + +#define NWCLEANUPGATEWAYSHARES_NAME "NwCleanupGatewayShares" +#define NWPROVAU_DLL_NAME L"NWPROVAU" + +/******************************************************************* + + NAME: DeleteGatewayPassword + + SYNOPSIS: delete the LSA secret used for gateway password. + also clears the NWCS installed bit. INF will be + changed to call CleanupRegistryForNWCS, but this entry + point is left here to handle DLL/INF mismatch. + + ENTRY: NONE from inf file. + + RETURN: BOOL - TRUE for success. + (always return TRUE) + + HISTORY: + chuckc 29-Oct-1993 Created + +********************************************************************/ + +BOOL FAR PASCAL +DeleteGatewayPassword( + DWORD nArgs, + LPSTR apszArgs[], + LPSTR * ppszResult + ) +{ + return TRUE ; // work is done in cleanup below which does everything. +} + +/******************************************************************* + + NAME: CleanupRegistryForNWCS + + SYNOPSIS: delete the LSA secret used for gateway password. + also set flag that NWCS has been removed. this flag + is used by wfwnet.drv. + + ENTRY: NONE from inf file. + + RETURN: BOOL - TRUE for success. + (always return TRUE) + + HISTORY: + chuckc 29-Oct-1993 Created + +********************************************************************/ + +BOOL FAR PASCAL +CleanupRegistryForNWCS( + DWORD nArgs, + LPSTR apszArgs[], + LPSTR * ppszResult + ) +{ + HANDLE hDll ; + DWORD err = 0, err1 = 0 ; + LPNWCLEANUPGATEWAYSHARES lpfnNwCleanupGatewayShares = NULL ; + + (void) nArgs ; // quiet the compiler + (void) apszArgs ; // quiet the compiler + + if (!WriteProfileStringA("NWCS", + "NwcsInstalled", + "0")) + { + err = GetLastError() ; + } + + err1 = NwDeletePassword(GATEWAY_USER) ; + + if (!err) + err = err1 ; + + if ((hDll = LoadLibraryW(NWPROVAU_DLL_NAME)) && + (lpfnNwCleanupGatewayShares = (LPNWCLEANUPGATEWAYSHARES) + GetProcAddress(hDll, NWCLEANUPGATEWAYSHARES_NAME))) + { + err1 = (*lpfnNwCleanupGatewayShares)() ; + (void) FreeLibrary(hDll) ; + } + + // + // ignore errors for this. + // + (void) SetupShellExtensions( + RegDeleteEntries, + sizeof(RegDeleteEntries)/sizeof(RegDeleteEntries[0])) ; + + if (!err) + err = err1 ; + + wsprintfA( achBuff, "{\"%d\"}", err ); + *ppszResult = achBuff; + + return TRUE; +} + +/******************************************************************* + + NAME: SetupShellExtensions + + SYNOPSIS: setup the registry for shell extensions. function is driven + by a table of entries (RegEntries). for each entry there is a + Operation code that tells us what we are doing. key entries can + be created absolute or relative to previous positions, so we + maintain a stack of registry handles for the latter case. every + key that is created is initially put on the stack. values + are always written based on the 'current stack' position. + + ENTRY: NONE + + RETURN: Win32 error code + + HISTORY: + chuckc 29-Nov-1995 Created + +********************************************************************/ +DWORD SetupShellExtensions(REG_ENTRY RegEntries[], DWORD dwNumEntries) +{ + DWORD err, errClose, dwDisposition, i ; + HKEY hKey, RegHandleStack[MAX_REG_LEVEL] ; + LONG StackIndex = -1 ; + + // + // Loop thru and for each entry. Then switch & do the appropriate + // operation in the registry. + // + + for (i = 0; i < dwNumEntries; i++) + { + err = NO_ERROR ; + + switch (RegEntries[i].Operation) + { + case CREATE_ABS: + + // + // create/open a reg key with an absolute path. since this + // is absolute, we drop everything on the stack, and start + // all over again. + // + + while (StackIndex >= 0) + { + errClose = RegCloseKey(RegHandleStack[StackIndex--]) ; + ASSERT(errClose == NO_ERROR) ; + } + + err = RegCreateKeyExW(HKEY_LOCAL_MACHINE, + RegEntries[i].s1, // subkey + 0, // reserved + NULL, // class + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + NULL, // default security + &hKey, + &dwDisposition) ; // not used + if (err != NO_ERROR) + { + break ; + } + + // + // by default we advance the stack. no need check for overflow + // as the stack is empty. + // + + RegHandleStack[++StackIndex] = hKey ; + break ; + + case CREATE_REL: + + // + // create/open a reg key relative to current stack. make sure + // there is something on the stack (check StackIndex >= 0). + // then see if we are advancing (+1), staying the same (0) or + // dropping back (-ve). + // + + if (StackIndex < 0) + { + err = ERROR_INVALID_FUNCTION ; + break ; + } + + if (RegEntries[i].Level == +1) + { + // + // opening next level down. continue as is and use + // most recently opened key as the starting point. + // + } + else if (RegEntries[i].Level == 0) + { + // + // opening at same level as last time. so we are done + // with the last key. what we want to do is close it + // and use the parent. + // + errClose = RegCloseKey(RegHandleStack[StackIndex--]) ; + + ASSERT(errClose == NO_ERROR) ; + + if (StackIndex < 0) + { + err = ERROR_INVALID_FUNCTION ; + break ; + } + } + else if (RegEntries[i].Level < 0) + { + // + // dropping back & opening at a higher level. cleanup + // handle for each level we pop. + // + + LONG Count = RegEntries[i].Level ; + + while (Count++ < 1) + { + errClose = RegCloseKey(RegHandleStack[StackIndex--]) ; + + ASSERT(errClose == NO_ERROR) ; + + if (StackIndex < -1) + { + err = ERROR_INVALID_FUNCTION ; + break ; + } + } + } + else + { + // + // only -ve numbers, 0 and 1 are valid + // + + err = ERROR_INVALID_FUNCTION ; + break ; + } + + // + // create key relative to current point + // + err = RegCreateKeyExW(RegHandleStack[StackIndex], // current key + RegEntries[i].s1, // subkey + 0, // reserved + NULL, // class + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + NULL, // default security + &hKey, + &dwDisposition) ; // not used + if (err != NO_ERROR) + { + break ; + } + + // + // by default we advance the stack + // + + RegHandleStack[++StackIndex] = hKey ; + + if (StackIndex >= MAX_REG_LEVEL) + { + err = ERROR_INVALID_FUNCTION ; + break ; + } + + break ; + + case VALUE_STR: + + // + // create a REG_SZ value at current point. check we have + // handle on stack. + // + + if (StackIndex < 0) + { + err = ERROR_INVALID_FUNCTION ; + break ; + } + + err = RegSetValueExW( + RegHandleStack[StackIndex], // current key + RegEntries[i].s1, // value name + 0, // reserved + REG_SZ, + (BYTE *)RegEntries[i].s2, // value data + (wcslen(RegEntries[i].s2)+1)*sizeof(WCHAR)) ; + break ; + + case DELETE_ABS: + + // + // delete a key (absolute). no change to stack. + // + + err = RegDeleteKeyW(HKEY_LOCAL_MACHINE, + RegEntries[i].s1) ; // subkey + + if ( err == ERROR_FILE_NOT_FOUND ) + err = NO_ERROR; + + break ; + + case DELETE_REL: + + // + // delete a key (relative). no change to stack. + // + + if (StackIndex < 0) + { + err = ERROR_INVALID_FUNCTION ; + break ; + } + + err = RegDeleteKeyW(RegHandleStack[StackIndex], // current key + RegEntries[i].s1) ; // subkey + + if ( err == ERROR_FILE_NOT_FOUND ) + err = NO_ERROR; + + break ; + + case DELETE_VAL: + + // + // delete value at current point. check we have handle on stack. + // + + if (StackIndex < 0) + { + err = ERROR_INVALID_FUNCTION ; + break ; + } + + err = RegDeleteValueW(RegHandleStack[StackIndex], // current key + RegEntries[i].s1) ; // value name + break ; + + case DROP_STACK: + + // + // drop current stack by one (closing the handle). + // + + if (StackIndex < 0) + { + err = ERROR_INVALID_FUNCTION ; + break ; + } + + errClose = RegCloseKey(RegHandleStack[StackIndex--]) ; + + ASSERT(errClose == NO_ERROR) ; + + break ; + + default: + + // + // error out if unknown operation + // + + err = ERROR_INVALID_FUNCTION ; + break ; + } + + if (err != NO_ERROR) + { + break ; + } + } + + // + // cleanup open handles on the stack + // + + while (StackIndex >= 0) + { + errClose = RegCloseKey(RegHandleStack[StackIndex--]) ; + ASSERT(errClose == NO_ERROR) ; + } + + return err ; +} |