KERNEL: pull WINDIR and WINSYSDIR from config before using hardcoded defaults (possible fix for WWN #234, #235 c:\\windows is not accessible Error)

Alex Villací­s Lasso a_villacis at palosanto.com
Wed Aug 18 17:29:14 CDT 2004


* Are you experiencing the following messages on each and every start of 
Wine?:
|
    Warning: the specified Windows directory L"C:\\Windows" is not 
accessible.
    Warning: the specified System directory L"C:\\Windows\\System" is 
not accessible.

* Is your wine installation failing to find your native DLLs even when 
the files
  exist in the WinNT/Win2k system directory? (such as MFC42.DLL)

If so, please check whether both of these conditions are true:

1) You are using a Windows partition as your native Wine partition (that 
is, not a standalone wine install)
2) Your WINDIR is something other than ¨C:\windows¨, such as ¨C:\winnt¨, 
or ¨D:\windows¨, etc

If so, then you might be lucky - this patch will solve the problem (or 
at least it does in my machine).

What is going on:

The source file dlls/kernel/process.c has a function called 
init_windows_dirs(), which is supposed
to create suitable values for %WINDIR% and %WINSYSDIR%. This function, 
as far as I can tell, is
just querying the environment for the values of windir and winsysdir 
(therefore, executing
¨windir=C:\\winnt winsysdir=C:\\winnt\\system32 wine yourprogram.exe¨ 
can be used as a workaround).
If these environment variables are not found, the function uses the 
hardcoded values ¨C:\windows¨
and ¨C:\windows\system¨ as %WINDIR% and %WINSYSDIR%. Later in the same 
function, there is a check
to see whether the chosen values %WINDIR% and %WINSYSDIR% are 
accessible. If the directories do not
exist, the function prints the messages you see at Wine start.

Apparently, the %WINSYSDIR% is also used as part of the path to search 
for system DLLs. Applications
which reference native DLLs for which Wine has no builtin replacement 
will fail to load if the DLLs
exists but are located at a nonstandard %WINSYSDIR% (for example, 
msdev.exe, the Visual C++ IDE, which
requires MFC42.DLL).

What the patch does:

The patch attempts to pull the values of ¨windows¨ and ¨system¨ under 
the [wine] section of the config
file. If the values are not found, the function will again fall back to 
the hardcoded values.

This problem is analyzed in the Weekly Newsletters #234 and #235. Please 
test this patch and tell if it
actually solves the two related problems.

Changelog:
* if windir or winsysdir environment vars are undefined, pull values 
from config file before falling to hardcoded values


Alex Villacis Lasso

|
-------------- next part --------------
--- wine-20040813/dlls/kernel/process.c	2004-08-04 13:15:04.000000000 -0500
+++ wine-20040813-patch/dlls/kernel/process.c	2004-08-18 16:46:52.000000000 -0500
@@ -806,6 +806,24 @@
     static const WCHAR default_windirW[] = {'c',':','\\','w','i','n','d','o','w','s',0};
     static const WCHAR default_sysdirW[] = {'\\','s','y','s','t','e','m',0};
 
+    static const WCHAR wineConfigKey[] = 
+    {'M','a','c','h','i','n','e','\\',
+     'S','o','f','t','w','a','r','e','\\',
+     'W','i','n','e','\\',
+     'W','i','n','e','\\',
+     'C','o','n','f','i','g','\\',
+     'w','i','n','e', 0};
+    static const WCHAR windirConfigKey[] = {'w','i','n','d','o','w','s',0};
+    static const WCHAR winsysdirConfigKey[] = {'s','y','s','t','e','m',0};
+    HKEY hkey;
+    OBJECT_ATTRIBUTES attr;
+    UNICODE_STRING valueW;
+    UNICODE_STRING keyW;
+    NTSTATUS status;
+    char bufferKey[1024 + sizeof(KEY_VALUE_FULL_INFORMATION)];
+    DWORD size;
+    KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)bufferKey;
+
     DWORD len;
     WCHAR *buffer;
 
@@ -815,15 +833,59 @@
         GetEnvironmentVariableW( windirW, buffer, len );
         DIR_Windows = buffer;
     }
-    else DIR_Windows = default_windirW;
+    else
+    {
+        attr.Length = sizeof(attr);
+        attr.RootDirectory = 0;
+        attr.ObjectName = &valueW;
+        attr.Attributes = 0;
+        attr.SecurityDescriptor = NULL;
+        attr.SecurityQualityOfService = NULL;
+
+        RtlInitUnicodeString(&valueW, wineConfigKey);
+        if (NtOpenKey(&hkey, KEY_ALL_ACCESS, &attr) == STATUS_SUCCESS)
+        {
+            RtlInitUnicodeString(&keyW, windirConfigKey);
+            status = NtQueryValueKey(hkey, &keyW, KeyValueFullInformation,
+                bufferKey, sizeof(bufferKey), &size);
+            if (status == STATUS_SUCCESS && info->Type == REG_SZ) {
+                buffer = HeapAlloc(GetProcessHeap(), 0, info->DataLength + 2);
+                memcpy(buffer, bufferKey + info->DataOffset, info->DataLength + 2);
+                DIR_Windows = buffer;
+            }
+            NtClose(hkey);
+        }
+        if (DIR_Windows == NULL) DIR_Windows = default_windirW;
+    }
 
     if ((len = GetEnvironmentVariableW( winsysdirW, NULL, 0 )))
     {
         buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
         GetEnvironmentVariableW( winsysdirW, buffer, len );
         DIR_System = buffer;
+    } else {
+        attr.Length = sizeof(attr);
+        attr.RootDirectory = 0;
+        attr.ObjectName = &valueW;
+        attr.Attributes = 0;
+        attr.SecurityDescriptor = NULL;
+        attr.SecurityQualityOfService = NULL;
+
+        RtlInitUnicodeString(&valueW, wineConfigKey);
+        if (NtOpenKey(&hkey, KEY_ALL_ACCESS, &attr) == STATUS_SUCCESS)
+        {
+            RtlInitUnicodeString(&keyW, winsysdirConfigKey);
+            status = NtQueryValueKey(hkey, &keyW, KeyValueFullInformation,
+                bufferKey, sizeof(bufferKey), &size);
+            if (status == STATUS_SUCCESS && info->Type == REG_SZ) {
+                buffer = HeapAlloc(GetProcessHeap(), 0, info->DataLength + 2);
+                memcpy(buffer, bufferKey + info->DataOffset, info->DataLength + 2);
+                DIR_System = buffer;
+            }
+            NtClose(hkey);
+        }
     }
-    else
+    if (DIR_System == NULL)
     {
         len = strlenW( DIR_Windows );
         buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) + sizeof(default_sysdirW) );


More information about the wine-patches mailing list