2015-08-26 5 views
0

Мне нужно получить доступ к файлу с отображением памяти с одного из моих маршрутов в моем веб-API. Используя обычные рабочие параметры IIS, мне не повезло, и моя служба всегда возвращает «Файл не найден». Я попытался добавить префикс «Global /», но все равно не повезло.Поднятие идентификатора рабочего лица IIS для доступа к файлу с памятью памяти

Прочитав много часов в Интернете, я узнал, что мне нужно изменить Identity рабочего IIS. Итак, только для целей тестирования я изменил идентификатор работника на учетную запись администратора. Я загрузил фотографию здесь:

http://imgur.com/MrA3byz

Но до сих пор нет удачи. Кто-нибудь знает, как правильно настроить IIS?

Вот как получить доступ к памяти файла, отображенной с помощью C#:

string Message = ""; 

try 
{ 
    string MMF_In_Name = "Global\\MMF_Name"; 
    MemoryMappedFile MMF_In = MemoryMappedFile.OpenExisting(MMF_In_Name); 

    Messages.Add("Connected to MMF"); 
} 
catch (Exception ex) 
{ 
    Messages.Add(ex.Message); 
} 

Я дважды проверил имя памяти отображается файл, и это правильно. Инструмент командной строки, выполняемый как Администратор, работает как ожидалось.

Я использую IIS 8.5 на Windows Server 2012.

+0

Что касается Windows, рабочий процесс IIS идентичен любому другому процессу и имеет все права доступа к учетной записи пользователя, в которой он работает. Вы уверены, что код верен? Можете ли вы успешно открыть файл, если f.e. вы запускаете тот же код в стандартном процессе? – Massimo

+0

Да, я могу успешно использовать файл с памятью. В другом потоке кто-то сказал мне, что мне нужно создать файл с префиксом «Global /». Я тоже попробую. – chhenning

+0

Это * COULD * будет еще одной проблемой UAC (хотя она должна влиять на стандартный процесс так же, как и процесс IIS). Можете ли вы попробовать отключить UAC? – Massimo

ответ

0

Это работает на Windows Server 2012 и IIS 8.5.

Важно понимать, что рабочий IIS работает на другом сеансе сервера терминалов, чем обычные приложения. Очень похоже на службу Windows.

Поэтому, когда приложение, открывающее файл с памятью, ему нужно создать его с помощью префикса «Глобальный», добавленного к имени. Но также необходимо добавить дескриптор безопасности или идентификатор. В C# это будет выглядеть следующим образом:

string MMF_Name = @"Global\MyMemoryMappedFileName"; 

var security = new MemoryMappedFileSecurity(); 
security.AddAccessRule(new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(new SecurityIdentifier(WellKnownSidType.WorldSid, null) 
    , MemoryMappedFileRights.FullControl 
    , AccessControlType.Allow) 
    ); 


var mmf = MemoryMappedFile.CreateOrOpen(MMF_Name 
    , 1024 * 1024 
    , MemoryMappedFileAccess.ReadWrite 
    , MemoryMappedFileOptions.None 
    , security 
    , System.IO.HandleInheritability.Inheritable); 

В C++ это будет выглядеть следующим образом:

TCHAR szName[] = TEXT("Global\MyMemoryMappedFileName"); 

HANDLE hMapFile; 
LPCTSTR pBuf; 

SECURITY_DESCRIPTOR sd; 

if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) 
    printf("InitializeSecurityDescriptor failed %d\n", GetLastError()); 

if (!SetSecurityDescriptorDacl(&sd, true, 0, false)) 
    printf("SetSecurityDescriptorDacl failed %d\n", GetLastError()); 

SECURITY_ATTRIBUTES sa; 
sa.nLength = sizeof(sa); 
sa.lpSecurityDescriptor = &sd; 
sa.bInheritHandle = false; 



hMapFile = CreateFileMapping(
    INVALID_HANDLE_VALUE, // use paging file 
    &sa,     // default security 
    PAGE_READWRITE,   // read/write access 
    0,      // maximum object size (high-order DWORD) 
    BUF_SIZE,    // maximum object size (low-order DWORD) 
    szName);     // name of mapping object 

if (hMapFile == NULL) 
{ 
    _tprintf(TEXT("Could not create file mapping object (%d).\n"), 
     GetLastError()); 
    return 1; 
} 

Приложение создания таких объектов необходимо начать с правами администратора.

Теперь, когда клиент, как и работник IIS, пытается получить доступ к файлу, ему необходимо использовать правильное имя, а также использовать префикс «Глобальный». В C# это будет выглядеть так:

string MMF_Name = @"Global\MyMemoryMappedFileName"; 

var MMF = MemoryMappedFile.OpenExisting(MMF_Name 
    , MemoryMappedFileRights.ReadWrite 
    , HandleInheritability.Inheritable); 

В C++:

TCHAR szName[] = TEXT("Global\\MyMemoryMappedFileName"); 

HANDLE hMapFile; 
LPCTSTR pBuf; 

hMapFile = OpenFileMapping(
    FILE_MAP_ALL_ACCESS, // read/write access 
    TRUE,     // !!!!! do inherit the name 
    szName);    // name of mapping object 

if (hMapFile == NULL) 
{ 
    _tprintf(TEXT("Could not open file mapping object (%d).\n"), 
     GetLastError()); 
    return 1; 
} 

Когда все это сделано. Работник IIS должен иметь доступ к приложению через файл с отображением памяти. Не нужно менять личность работника. Фактически, я запускаю его в настройках по умолчанию.