我对我的问题进行了很多研究,发现了许多与[如何将字符串从c#
传递到c
dll ]有关的问题:
但是他们谁也帮不了我。我更喜欢问我的问题:
简要说明:
当我从以下位置交换c
参数(在c#
dll和GetProcessIntegrityLevel
import-dll中)时,我的c
函数在c#
中正常工作: / p>
BOOL GetProcessIntegrityLevel(DWORD dwPID, LPSTR szIntegrityLevel);
对此:
BOOL GetProcessIntegrityLevel(LPSTR szIntegrityLevel, DWORD dwPID);
在第一种状态下,我的程序可以正常运行并更改LPSTR szIntegrityLevel
,但是在第二种状态下,它无法正常工作,LPSTR szIntegrityLevel
始终为空且没有任何pid。
我创建了一个c
dll库,在其中我 声明了 以下获得{em> c
的{{1}}函数< / em>通过pid进行处理:
Integrity Level
C函数实现:
#define MAX_INTEGRITY_LEVEL_LENGTH 30
extern "C"
{
__declspec(dllexport) BOOL GetProcessIntegrityLevel(DWORD dwPID, LPSTR szIntegrityLevel);
}
因此,我从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()
dll中导入c
,如下所示:
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
函数和c
函数中互换参数时,它确实起作用:
c#
这对我来说很奇怪。我也尝试了__declspec(dllexport) BOOL GetProcessIntegrityLevel(LPSTR szIntegrityLevel, DWORD dwPID);
,但给了我相同的结果。
答案 0 :(得分:1)
在C#中,ulong
是64位类型。 PID参数是DWORD
,它是一个32位参数。
将C#参数声明从ulong
更改为uint
,以解决问题。