Index: dll/win32/kernel32/client/file/deviceio.c =================================================================== --- dll/win32/kernel32/client/file/deviceio.c (revision 67982) +++ dll/win32/kernel32/client/file/deviceio.c (working copy) @@ -128,6 +128,85 @@ return TRUE; } + +ULONG g_TSAppCompat = -1; + +BOOL +IsTSAppCompatEnabled() +{ + /* This is a TROOLEAN, -1 means we haven't yet figured it out. + name stolen from client\appcache.c */ + if (g_TSAppCompat == -1) + { + OSVERSIONINFOEXW VersionInfo = {0}; + VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo); + if (GetVersionExW((LPOSVERSIONINFOW)&VersionInfo)) + { + /* If VER_SUITE_TERMINAL is set but VER_SUITE_SINGLEUSERTS is not set, + the system is running in application server mode. */ + WORD TSState = VersionInfo.wSuiteMask & (VER_SUITE_TERMINAL|VER_SUITE_SINGLEUSERTS); + g_TSAppCompat = (TSState == VER_SUITE_TERMINAL) ? TRUE : FALSE; + } + else + { + g_TSAppCompat = FALSE; + } + } + return g_TSAppCompat; +} + +BOOL +IsCallerAdminOrSystem() +{ + BOOL IsAdminOrSystem = FALSE; + HMODULE hAdvapi = LoadLibraryA("advapi32.dll"); + BOOL (WINAPI* pCheckTokenMembership)(HANDLE,PSID,PBOOL) = NULL; + pCheckTokenMembership = (void *)GetProcAddress(hAdvapi, "CheckTokenMembership"); + if (pCheckTokenMembership) + { + SID_IDENTIFIER_AUTHORITY SidAuthority = {SECURITY_NT_AUTHORITY}; + PSID pSid = NULL; + NTSTATUS Status = RtlAllocateAndInitializeSid(&SidAuthority, 2, + SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSid); + if (NT_SUCCESS(Status)) + { + if (pCheckTokenMembership(NULL, pSid, &IsAdminOrSystem)) + { + SetLastError(IsAdminOrSystem ? 0 : ERROR_ACCESS_DENIED); + } + } + else + { + IsAdminOrSystem = FALSE; + BaseSetLastNTError(Status); + } + if (pSid) + RtlFreeSid(pSid); + if (!IsAdminOrSystem) + { + Status = RtlAllocateAndInitializeSid(&SidAuthority, 1, + SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSid); + if (NT_SUCCESS(Status)) + { + if (pCheckTokenMembership(NULL, pSid, &IsAdminOrSystem)) + { + SetLastError(IsAdminOrSystem ? 0 : ERROR_ACCESS_DENIED); + } + } + else + { + IsAdminOrSystem = FALSE; + BaseSetLastNTError(Status); + } + if (pSid) + RtlFreeSid(pSid); + } + } + if (hAdvapi) + FreeLibrary(hAdvapi); + return IsAdminOrSystem; +} + /* * @implemented */ @@ -147,13 +226,19 @@ PVOID ApcContext; IO_STATUS_BLOCK Iosb; - // - // Note: on a TS Machine, we should call IsTSAppCompatEnabled and unless the - // IOCTLs are IOCTL_STORAGE_EJECT_MEDIA, IOCTL_DISK_EJECT_MEDIA, FSCTL_DISMOUNT_VOLUME - // we should call IsCallerAdminOrSystem and return STATUS_ACCESS_DENIED for - // any other IOCTLs. - // + if (dwIoControlCode != IOCTL_STORAGE_EJECT_MEDIA && + dwIoControlCode != IOCTL_DISK_EJECT_MEDIA && + dwIoControlCode != FSCTL_DISMOUNT_VOLUME && + IsTSAppCompatEnabled()) + { + if (!IsCallerAdminOrSystem()) + { + BaseSetLastNTError(STATUS_ACCESS_DENIED); + return FALSE; + } + } + /* Check what kind of IOCTL to send */ FsIoCtl = ((dwIoControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM);