dbf.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 8k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  *  dbf.c
  3.  *
  4.  *  old registry stubs that call through to those now in kernel.
  5.  *
  6.  *  implement any compatibility hacks here.
  7.  *
  8.  *  currently we map the win 3.1 predefined keys (HKEY_CLASSES_ROOT)
  9.  *  to the NT definitions (0x80000000).  real chicago apps should
  10.  *  not call these APIs since they are now in kernel.
  11.  *
  12.  *  The old registry APIs returned ERROR_BADKEY for invalid HKEY passed
  13.  *  in and used CANTOPEN only for unable to open registry file. The new
  14.  *  NT compatile registry code uses BADKEY to indicate invalid subkey and
  15.  *  CANTOPEN for invalid HKEY passed in. Since the only call where CANTOPEN
  16.  *  in the old meaning could be returned from the new code is FLUSHKEY,
  17.  *  we will always translate CANTOPEN to BADKEY.
  18.  */
  19. #include "shprv.h"
  20. #include <winerror.h>
  21. /* these are the error codes from Win 3.1 Windows.h */
  22. #define MY_ERROR_BADDB             1L
  23. #define MY_ERROR_BADKEY            2L
  24. #define MY_ERROR_CANTOPEN          3L
  25. #define MY_ERROR_CANTREAD          4L
  26. #define MY_ERROR_CANTWRITE         5L
  27. #define MY_ERROR_OUTOFMEMORY       6L
  28. #define MY_ERROR_INVALID_PARAMETER 7L
  29. #define MY_ERROR_ACCESS_DENIED     8L
  30. /* end of win 3.1 registry error codes */
  31. /*
  32.  * RegErrorMap
  33.  * Win 3.1 compatibility error code mapping
  34.  *  Called after a VMM Registry call to map the Win32 Error code
  35.  * we get back from VMM to win 3.1 error codes for App 
  36.  * compatibility.
  37.  * Entry: NewErrorCode  WIN32 Registry error code
  38.  * Exit: Win3.1 equivalent error code
  39.  *
  40. */
  41. LONG NEAR _fastcall RegErrorMap(LONG NewErrCode)
  42. {
  43. // Successful -> no mapping 
  44. if (NewErrCode == ERROR_SUCCESS)
  45. return (ERROR_SUCCESS);
  46. /* map the new NT error code to old win 3.1 error */
  47. switch (NewErrCode) {
  48.     case ERROR_REGISTRY_CORRUPT:
  49.     case ERROR_BADDB:
  50. return(MY_ERROR_BADDB);
  51.     case ERROR_REGISTRY_IO_FAILED:
  52.     case ERROR_CANTWRITE:
  53. return(MY_ERROR_CANTWRITE);
  54.     case ERROR_BADKEY:
  55.     case ERROR_KEY_DELETED:
  56.     case ERROR_CANTOPEN:
  57.             case ERROR_FILE_NOT_FOUND:
  58.             case ERROR_NO_MORE_ITEMS:
  59. return(MY_ERROR_BADKEY);           
  60.     case ERROR_CANTREAD:
  61. return (MY_ERROR_CANTREAD);
  62.     case ERROR_INVALID_PARAMETER:
  63. return (MY_ERROR_INVALID_PARAMETER);
  64.     case ERROR_INSUFFICIENT_BUFFER:
  65.     case ERROR_MORE_DATA:
  66.     case ERROR_OUTOFMEMORY:
  67.     case ERROR_NOT_ENOUGH_MEMORY:         
  68. return(MY_ERROR_OUTOFMEMORY);
  69.     default:
  70. return(MY_ERROR_ACCESS_DENIED);
  71. }
  72. }
  73. static char g_szClasses[] = ".classes";
  74. //  Very old applications may use an HKEY of 0 and specify a subkey starting
  75. //  with .classes.  This is actually HKEY_CLASSES_ROOT, so we must strip off
  76. //  the .classes to get at the subkey name.
  77. //
  78. //  NT's WOW32.DLL does the same thing (wshell.c).
  79. LPCSTR NEAR _fastcall SkipClasses(LPCSTR lpSubKey)
  80. {
  81.     PSTR pStr;
  82.     LPCSTR lpRealSubKey;
  83.     if (HIWORD(lpSubKey) != NULL) {
  84.         pStr = g_szClasses;
  85.         lpRealSubKey = lpSubKey;
  86.         while ((*pStr != '') &&
  87.             ((char)(WORD)(DWORD)AnsiLower((LPSTR)(DWORD)(BYTE)*lpRealSubKey) ==
  88.             *pStr)) {
  89.             pStr++;
  90.             lpRealSubKey++;
  91.         }
  92.         if (*pStr == '') {
  93.             if (*lpRealSubKey == '\')
  94.                 lpRealSubKey++;
  95.             return lpRealSubKey;
  96.         }
  97.     }
  98.     return lpSubKey;
  99. }
  100. LONG WINAPI MyRegOpenKey(HKEY hkey, LPCSTR lpSubKey, LPHKEY phkResult)
  101. {
  102.     switch (hkey) {
  103.         case 0:     lpSubKey = SkipClasses(lpSubKey);
  104.         case 1:     hkey = 0x80000000;
  105.     }
  106.     
  107.     return RegErrorMap(RegOpenKey(hkey, lpSubKey, phkResult));
  108. }
  109. LONG WINAPI MyRegCreateKey(HKEY hkey, LPCSTR lpSubKey, LPHKEY phkResult)
  110. {
  111.     switch (hkey) {
  112.         case 0:     lpSubKey = SkipClasses(lpSubKey);
  113.         case 1:     hkey = 0x80000000;
  114.     }
  115.     
  116.     return RegErrorMap(RegCreateKey(hkey, lpSubKey, phkResult));
  117. }
  118. LONG WINAPI MyRegDeleteKey(HKEY hkey, LPCSTR lpSubKey)
  119. {
  120.     //  B#6898(WIN95D):  Microsoft Office 4.2 and 4.3 delete tons of subkeys that
  121.     //  they shouldn't touch during their uninstall (such as CLSID).  They
  122.     //  somehow incorrectly link the fact that they didn't upgrade ole2.dll
  123.     //  (stamped 2.1 in Win95, 2.01 in Win3.1) to the need to purge the registry
  124.     //  of all ole2.reg items.
  125.     //
  126.     //  Because Win95 kinda needs the CLSID branch around for the shell to work,
  127.     //  we add this special hack to check if the calling task is Acme setup and
  128.     //  if the Office setup extension DLL is around.  If so, return access
  129.     //  denied.  Their mssetup.dll doesn't check the return value, so any error
  130.     //  code will do.
  131.     if (hkey == 1) {
  132.         char szModule[10];              //  eight chars+null+padding
  133.         szModule[0] = '';             //  for safety.
  134.         if (GetModuleName(GetCurrentTask(), szModule, sizeof(szModule)) &&
  135.             (lstrcmp(szModule, "ACMSETUP") == 0) &&
  136.             (GetModuleHandle("OFF40_BB") != NULL)) {
  137.             return MY_ERROR_ACCESS_DENIED;
  138.         }
  139.     }
  140.     switch (hkey) {
  141.         case 0:     lpSubKey = SkipClasses(lpSubKey);
  142.         case 1:     hkey = 0x80000000;
  143.     }
  144.     
  145.     return RegErrorMap(RegDeleteKey(hkey, lpSubKey));
  146. }
  147. LONG WINAPI MyRegCloseKey(HKEY hkey)
  148. {
  149.     switch (hkey) {
  150.         case 0:
  151.         case 1:     hkey = 0x80000000;
  152.     }
  153.     
  154.     return RegErrorMap(RegCloseKey(hkey));
  155. }
  156. LONG WINAPI MyRegQueryValue(HKEY hkey, LPCSTR lpSubKey, LPSTR lpValue, LONG FAR * lpcb)
  157. {
  158.     LONG     rc;
  159.     DWORD    cbOriginalValue;
  160.     LPBYTE   lpByte = NULL;
  161.     // Fix MSTOOLBR.DLL unintialized cbValue by forcing it to be less than 64K
  162.     // Win 3.1 Registry values are always less than 64K.
  163.     cbOriginalValue = LOWORD(*lpcb);
  164.     switch (hkey) {
  165.         case 0:     lpSubKey = SkipClasses(lpSubKey);
  166.         case 1:     hkey = 0x80000000;
  167.     }
  168.     rc = RegQueryValue(hkey, lpSubKey, lpValue, lpcb);
  169.     //  In Win3.1, if you tried to query a value that wouldn't fit into the
  170.     //  output buffer, then only the originally specified number of bytes would
  171.     //  be copied and ERROR_SUCCESS would be returned.  WordPerfect 6.1 appears
  172.     //  to have forgetten to reset 'lpcb' on their next call to RegQueryValue,
  173.     //  so it is dependent on this fact (or else it will put up an error message
  174.     //  box).
  175.     if (rc == ERROR_MORE_DATA) {
  176.         lpByte = (LPBYTE) MAKELP(GlobalAlloc(GPTR, *lpcb), 0);
  177.         if (SELECTOROF(lpByte) == NULL) {
  178.             return MY_ERROR_OUTOFMEMORY;
  179.         }
  180.         rc = RegQueryValue(hkey, lpSubKey, lpByte, lpcb);
  181.         if (SELECTOROF(lpValue) && cbOriginalValue) {
  182.             hmemcpy(lpValue, lpByte, cbOriginalValue);
  183.             lpValue[cbOriginalValue - 1] = '';
  184.         }
  185.         GlobalFree(SELECTOROF(lpByte));
  186.         *lpcb = cbOriginalValue;
  187.     }
  188.     return RegErrorMap(rc);
  189. }
  190. LONG WINAPI MyRegSetValue(HKEY hkey, LPCSTR lpSubKey, DWORD dwType, LPCSTR lpValue, DWORD cbValue)
  191. {
  192.     switch (hkey) {
  193.         case 0:     lpSubKey = SkipClasses(lpSubKey);
  194.         case 1:     hkey = 0x80000000;
  195.     }
  196.     //  In 3.1, the cbValue parameter really wasn't used... the registry code
  197.     //  always calculated the size of the value as the string length of lpValue.
  198.     return RegErrorMap(RegSetValue(hkey, lpSubKey, dwType, lpValue, 0));
  199. }
  200. LONG WINAPI MyRegEnumKey(HKEY hkey, DWORD dwIndex, LPSTR lpValue, DWORD dwMax)
  201. {
  202.     switch (hkey) {
  203.         case 0:
  204.         case 1:     hkey = 0x80000000;
  205.     }
  206.     
  207.     return RegErrorMap(RegEnumKey(hkey,  dwIndex, lpValue, dwMax));
  208. }