如何创建仅Windows应用可访问的本地文件?权限配置求助
问题:创建仅当前应用可访问的Windows本地文件
开发Windows x86控制台应用,需创建本地文件供API处理,核心要求是仅该应用可访问,PC普通用户或管理员均无法直接访问该文件。
目前遇到的问题:
- 自行编写的代码中,即使应用以管理员权限运行,管理员仍能访问文件
- API拒绝文件句柄,提示“FILE ERROR”
- 尝试过Z盘路径、安全权限设置、subst驱动器链接文件夹、
DefineDosDevice()映射等方法,均未达到预期效果 - 添加安全属性时控制台报API错误5(FILE ERROR)
DefineDosDevice()创建的驱动器未正常生成,且显示容量为0字节
要求:不能要求用户安装RAM磁盘等第三方驱动,必须使用Windows标准功能实现。
现有创建文件的代码
bool CreateRestrictedFile(std::wstring& localFilePath) { // Step 1: Get the .hex file path wchar_t filePath[MAX_PATH]; if (SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, filePath) != S_OK) { std::cerr << "Failed to get folder path. Error:: " << GetLastError() << std::endl; return false; } localFilePath = std::wstring(filePath) + L"\\temp.hex"; // Step 2: Initialize security attributes SECURITY_ATTRIBUTES sa; SECURITY_DESCRIPTOR sd; if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { std::wcerr << L"Failed to initialize security descriptor. Error: " << GetLastError() << std::endl; return false; } // Step 3: Create a restricted security descriptor PACL pDacl = NULL; EXPLICIT_ACCESS ea[2] = {}; // Grant full access to the current process (needs to be unique for the app but not the admin which the app runs at) HANDLE hProcess = GetCurrentProcess(); HANDLE hProcessToken; if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) { std::wcerr << L"Failed to open process token. Error: " << GetLastError() << std::endl; return false; } DWORD tokenInfoLength = 0; GetTokenInformation(hProcessToken, TokenUser, NULL, 0, &tokenInfoLength); PTOKEN_USER tokenUser = (PTOKEN_USER)malloc(tokenInfoLength); if (!GetTokenInformation(hProcessToken, TokenUser, tokenUser, tokenInfoLength, &tokenInfoLength)) { std::wcerr << L"Failed to get token information. Error: " << GetLastError() << std::endl; CloseHandle(hProcessToken); free(tokenUser); return false; } PSID currentProcessSID = tokenUser->User.Sid; ea[0].grfAccessPermissions = GENERIC_ALL; // Full access ea[0].grfAccessMode = GRANT_ACCESS; ea[0].grfInheritance = NO_INHERITANCE; ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER; ea[0].Trustee.ptstrName = (LPWSTR)currentProcessSID; // Deny access to everyone else PSID everyoneSID = NULL; SID_IDENTIFIER_AUTHORITY worldAuthority = SECURITY_WORLD_SID_AUTHORITY; if (!AllocateAndInitializeSid(&worldAuthority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyoneSID)) { std::wcerr << L"Failed to allocate SID for 'Everyone'. Error: " << GetLastError() << std::endl; CloseHandle(hProcessToken); free(tokenUser); return false; } ea[1].grfAccessPermissions = GENERIC_ALL; // Deny all access ea[1].grfAccessMode = DENY_ACCESS; ea[1].grfInheritance = NO_INHERITANCE; ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea[1].Trustee.ptstrName = (LPWSTR)everyoneSID; DWORD result = SetEntriesInAcl(2, ea, NULL, &pDacl); if (result != ERROR_SUCCESS) { std::wcerr << L"Failed to create DACL. Error: #30005 : " << result << std::endl; FreeSid(everyoneSID); CloseHandle(hProcessToken); free(tokenUser); return false; } if (!SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE)) { std::wcerr << L"Failed to set DACL in security descriptor. Error: " << GetLastError() << std::endl; LocalFree(pDacl); FreeSid(everyoneSID); CloseHandle(hProcessToken); free(tokenUser); return false; } // Initialize SECURITY_ATTRIBUTES sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = &sd; sa.bInheritHandle = FALSE; // Prevent handle inheritance // Step 6: Create the file with restricted access and auto-delete on close hFileSecure = CreateFile( localFilePath.c_str(), GENERIC_READ | GENERIC_WRITE, // Read and write access 0, // No sharing: prevent other processes from accessing the file &sa, // Default security attributes CREATE_ALWAYS, // Always create a new file FILE_ATTRIBUTE_TEMPORARY /* | FILE_FLAG_DELETE_ON_CLOSE */, // Temp file, auto-delete on close NULL // No template file ); if (hFileSecure == INVALID_HANDLE_VALUE) { std::cerr << "Failed to create .hex file. Error: " << GetLastError() << std::endl; return false; } return true; }
尝试过的驱动器映射代码
// Map folder to drive letter if (DefineDosDevice(DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM, lpdriveLetter, lpTargetFolder)) { std::cout << "Drive W: successfully created!" << std::endl; }
内容的提问来源于stack exchange,提问作者Robbie
相关产品推荐
相关产品推荐

