Я много исследовал свою проблему и нашел много вопросов относительно [ как передать строку из c#
в c
dll ]:
Но никто из них не мог мне помочь. В любом случае, я предпочитаю задать свой вопрос:
Краткое объяснение:
Моя c
функция работает правильно в c#
, только когда я обмениваю параметры GetProcessIntegrityLevel
(как в c
dll, так и в c#
import-dll) из:
BOOL GetProcessIntegrityLevel(DWORD dwPID, LPSTR szIntegrityLevel);
На этот:
BOOL GetProcessIntegrityLevel(LPSTR szIntegrityLevel, DWORD dwPID);
В первом состоянии моя программа работает нормально и меняет LPSTR szIntegrityLevel
Но во втором она не работает, и LPSTR szIntegrityLevel
всегда пуст с любым pid.
Я создал библиотеку c
dll, в которой я объявил следующую c
функцию, которая получает Integrity Level
процесса через pid :
#define MAX_INTEGRITY_LEVEL_LENGTH 30
extern "C"
{
__declspec(dllexport) BOOL GetProcessIntegrityLevel(DWORD dwPID, LPSTR szIntegrityLevel);
}
Реализация функции C:
BOOL GetProcessIntegrityLevel(DWORD dwPID, LPSTR szIntegrityLevel)
{
BOOL bFlag = FALSE; // Return flag
HANDLE hToken = INVALID_HANDLE_VALUE; // Token handle
HANDLE hProcess = NULL; // Process handle
BOOL bProcToken = FALSE; // OpenProcessToken() result
BOOL bTokenInfo = FALSE; // GetTokenInformation() result
DWORD dwLengthNeeded = 0; // Token information length
DWORD dwError = ERROR_SUCCESS; // GetTokenInformation() last error
DWORD dwIntegrityLevel = 0; // Integrity level
PTOKEN_MANDATORY_LABEL pTIL = NULL; // Use as token information
// Open the process
hProcess = OpenProcess(MAXIMUM_ALLOWED | PROCESS_QUERY_LIMITED_INFORMATION,
FALSE, dwPID);
if (hProcess != NULL)
{
// Open process token
bProcToken = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
if (bProcToken == TRUE)
{
// Get token information
bTokenInfo = GetTokenInformation(hToken, TokenIntegrityLevel,
NULL, 0, &dwLengthNeeded);
if (bTokenInfo == FALSE)
{
dwError = GetLastError();
if (dwError == ERROR_INSUFFICIENT_BUFFER)
{
pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwLengthNeeded);
if (pTIL != NULL)
{
// Get token information
bTokenInfo = GetTokenInformation(hToken, TokenIntegrityLevel,
pTIL, dwLengthNeeded, &dwLengthNeeded);
if (bTokenInfo == TRUE)
{
// Get integrity level
dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid,
(DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1));
if (dwIntegrityLevel <= SECURITY_MANDATORY_LOW_RID)
{
// Low Integrity
StrCpyA(szIntegrityLevel, "Low");
}
else if ((dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID) &&
(dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID))
{
// Medium Integrity
StrCpyA(szIntegrityLevel, "Medium");
}
else if ((dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID) &&
(dwIntegrityLevel < SECURITY_MANDATORY_SYSTEM_RID))
{
// High Integrity
StrCpyA(szIntegrityLevel, "High");
}
else if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID)
{
// System Integrity
StrCpyA(szIntegrityLevel, "System");
}
else if (dwIntegrityLevel == SECURITY_MANDATORY_UNTRUSTED_RID)
{
// Untrusted integrity
StrCpyA(szIntegrityLevel, "Untrusted");
}
else
{
StrCpyA(szIntegrityLevel, "UnKnown");
}
bFlag = TRUE;
}
LocalFree(pTIL);
}
}
}
// Close token handle
CloseHandle(hToken);
}
// Close the process handle
CloseHandle(hProcess);
}
return bFlag;
}
Итак, я импортирую GetProcessIntegrityLevel()
из моей c
dll в c#
следующим образом:
// Define function pointers for using of c dll functions
[DllImport("ProcessesPropDll.dll",CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.Bool)]
// Get integrity level
static extern bool GetProcessIntegrityLevel(ulong dwPID, StringBuilder szIntegrityLevel);
И вызовите функцию в c#
следующим образом:
// Integrity level
StringBuilder integrityLevel = new StringBuilder(200);
if(GetProcessIntegrityLevel(11684, integrityLevel) == true)
{
MessageBox.Show(integrityLevel.ToString());
}
В этом состоянии, когда я запускаю программу, GetProcessIntegrityLevel()
возвращает true
, но integrityLevel
всегда пуст в окне сообщений для любого pid
!!!!
ur Удивительно, когда я обмениваю параметры в моей функции c
, а также в c#
, она работает:
__declspec(dllexport) BOOL GetProcessIntegrityLevel(LPSTR szIntegrityLevel, DWORD dwPID);
Это очень странно для меня. Также я пытался с MarshalAs(UnmanagedType.LPStr)]
, но дать мне тот же результат.