From: Mark H. <mha...@us...> - 2007-05-18 11:22:18
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15549 Modified Files: win32trace.cpp Log Message: Work better on Vista, by dealing with the 'access denied' errors that are likely when working in the 'Global\\' namespace. Index: win32trace.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32trace.cpp,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** win32trace.cpp 28 Jan 2005 00:02:23 -0000 1.13 --- win32trace.cpp 18 May 2007 11:22:17 -0000 1.14 *************** *** 46,58 **** const char *EVENT_EMPTY_OBJECT_NAME = "Global\\PythonTraceOutputEmptyEvent"; ! // Function to remove the "Global\\" prefix on NT4/9x static const char *FixupObjectName(const char *global_name) { ! OSVERSIONINFO info; ! info.dwOSVersionInfoSize = sizeof(info); ! GetVersionEx(&info); ! if (info.dwMajorVersion <= 4) // NT, 9x return strchr(global_name, '\\')+1; ! // 2000 or later - "Global\\" prefix OK. return global_name; } --- 46,80 ---- const char *EVENT_EMPTY_OBJECT_NAME = "Global\\PythonTraceOutputEmptyEvent"; ! // Global\\ etc goodness: ! // On NT4/9x, 'Global\\' is not understood and will fail. ! // On 2k/XP, anyone can create 'global' objects. ! // On Vista, you need elavated perms to create global objects - however, once ! // it has been created and permissions adjusted, a user with normal ! // permissions can open these global objects. ! // As a service generally will be able to create global objects, we want a ! // non-elevated Python to be capable of automatically using the global space ! // if it exists, but coping when it can't create such an object (a local ! // one is probably fine in such cases). ! // [Why bother?: without the Global namespace, a 'win32traceutil' running in ! // a 'Remote Desktop' session would not be able to see output from a ! // service - they have different local namespaces] ! ! // This means: ! // * We first check to see if the mutex exists in the local namespace. If it ! // does, it we use that namespace for all objects. ! // * We then try and create a mutex in the global namespace - if this works, we also ! // use the global namespace. ! // * We then create the mutex in our local namespace and use that for everything. ! // (Ack - the above is only true for CreateFileMapping - creating mutexes etc ! // works fine) ! ! // This behavior is controlled by a global variable set at mutex creation time. ! BOOL use_global_namespace = FALSE; ! static const char *FixupObjectName(const char *global_name) { ! if (!use_global_namespace) return strchr(global_name, '\\')+1; ! // global prefix is ok. return global_name; } *************** *** 435,439 **** if (!ok) return NULL; - // put the new object into sys Py_INCREF(Py_None); return Py_None; --- 457,460 ---- *************** *** 448,452 **** if (!ok) return NULL; - // put the new object into sys Py_INCREF(Py_None); return Py_None; --- 469,472 ---- *************** *** 614,617 **** --- 634,670 ---- assert(hMutex == NULL); + + // See comments re global namespace above - the problem child is + // CreateFileMapping - so we temporarily use that just to work out what + // namespace to use for our objects. + + // is the "Global\" namespace even possible? + OSVERSIONINFO info; + info.dwOSVersionInfoSize = sizeof(info); + GetVersionEx(&info); + BOOL global_ok = info.dwMajorVersion > 4; + if (global_ok) { + // see comments at top of file - if it exists locally, stick with + // local - use_global_namespace is still FALSE now, so that is the + // name we get. + HANDLE h = CreateFileMapping((HANDLE)-1, &sa, PAGE_READWRITE, 0, + BUFFER_SIZE, + FixupObjectName(MAP_OBJECT_NAME)); + if (GetLastError() != ERROR_ALREADY_EXISTS) { + // no local one exists - see if we can create it globally - if + // we can, we go global, else we stick with local. + HANDLE h2 = CreateFileMapping((HANDLE)-1, &sa, PAGE_READWRITE, + 0, BUFFER_SIZE, + FixupObjectName(MAP_OBJECT_NAME)); + use_global_namespace = h2 != NULL && GetLastError() == ERROR_ACCESS_DENIED; + if (h2) + CloseHandle(h2); + } + if (h) + CloseHandle(h); + } + // use_global_namespace is now set and will not change - all objects + // we use are in the same namespace. + hMutex = CreateMutex(&sa, FALSE, FixupObjectName(MUTEX_OBJECT_NAME)); if (hMutex==NULL) { |