CVS: winex/dlls/ntdll nt.c,1.20,1.21
[email protected] 12 Sep 2007 12:46:35 -0000
| Newsgroups | gmane.comp.emulators.winex.cvs |
|---|---|
| Message-ID | <[email protected]> |
Subject: winex/dlls/ntdll nt.c,1.20,1.21Update of /var/lib/cvsd/cvsroot/winex/dlls/ntdll
In directory agravaine:/tmp/cvs-serv14019/dlls/ntdll
Modified Files:
nt.c
Log Message:
Implement SystemProcessInformation class.
TRAC #1971
Partially implement the SystemProcessInformation class for NtQuerySystemInformation, at least sufficiently for the dbghelp minidump requirements. Quite a few of the returned structure members are not filled in currently and are just zeroed.
Index: nt.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/ntdll/nt.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- nt.c 12 Sep 2007 12:40:02 -0000 1.20
+++ nt.c 12 Sep 2007 12:46:33 -0000 1.21
@@ -16,6 +16,7 @@
#include "winternl.h"
#include "ntdll_misc.h"
+#include "tlhelp32.h"
#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
@@ -765,34 +766,143 @@
return 0;
}
+
/******************************************************************************
- * NtCreateMailslotFile [NTDLL.@]
- * ZwCreateMailslotFile [NTDLL.@]
+ * Helper for NtQuerySystemInformation
*/
-NTSTATUS WINAPI NtCreateMailslotFile(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8)
+static NTSTATUS SnapCreate (HANDLE *pSnap)
{
- FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4,x5,x6,x7,x8);
- return 0;
+ NTSTATUS Ret;
+
+ /* Create initial snapshot */
+ SERVER_START_REQ (create_snapshot)
+ {
+ req->flags = TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD;
+ req->inherit = 0;
+ req->pid = 0;
+ if ((Ret = wine_server_call_err (req)) == STATUS_SUCCESS)
+ *pSnap = reply->handle;
+ }
+ SERVER_END_REQ;
+
+ if (*pSnap == INVALID_HANDLE_VALUE)
+ ERR ("Unable to create process snapshot!\n");
+
+ return Ret;
}
-static NTSTATUS collectProcessInformation(void *buf, ULONG length, ULONG *resultLength){
- if (buf){
- FIXME("gather process information\n");
+/******************************************************************************
+ * Helper for NtQuerySystemInformation
+ */
+static NTSTATUS SnapGetNextProcess (HANDLE hSnap, DWORD LenLeft,
+ PSYSTEM_PROCESS_INFORMATION pSPI)
+{
+ NTSTATUS Ret;
+ CHAR ProcName[1024];
+ CHAR *pExeName;
+ DWORD Len, ExeLen;
+ STRING AnsiStr;
- /* FIXME!! return an error for now */
- return STATUS_ACCESS_VIOLATION;
- }
+ SERVER_START_REQ (next_process)
+ {
+ req->handle = hSnap;
+ req->reset = FALSE;
+ wine_server_set_reply (req, ProcName, sizeof (ProcName));
+ if ((Ret = wine_server_call_err (req)) == STATUS_SUCCESS)
+ {
+ ProcName[wine_server_reply_size (reply)] = 0;
+ memset (pSPI, 0, sizeof (*pSPI));
+ pSPI->dwThreadCount = reply->threads;
+ pSPI->dwBasePriority = reply->priority;
+ pSPI->dwProcessID = (DWORD)reply->pid;
+ pSPI->dwParentProcessID = (DWORD)reply->ppid;
+ }
+ }
+ SERVER_END_REQ;
- else{
- if (resultLength)
- *resultLength = 1024;
-
- return STATUS_ACCESS_VIOLATION;
- }
+ if (Ret != STATUS_SUCCESS)
+ return Ret;
+ if ((pExeName = strrchr (ProcName, '\\')))
+ pExeName++;
+ else
+ pExeName = ProcName;
- return STATUS_SUCCESS;
+ ExeLen = (strlen (pExeName) + 1) * sizeof (WCHAR);
+ Len = sizeof (*pSPI) + ExeLen +
+ (pSPI->dwThreadCount * sizeof (SYSTEM_THREAD_INFORMATION));
+
+ if (LenLeft < Len)
+ return STATUS_INFO_LENGTH_MISMATCH;
+
+ /* Place the exe name after the thread information array to match Windows */
+ pSPI->ProcessName.MaximumLength = ExeLen;
+ pSPI->ProcessName.Buffer = (LPWSTR)((CHAR *)pSPI + Len - ExeLen);
+ RtlInitAnsiString (&AnsiStr, pExeName);
+ if (RtlAnsiStringToUnicodeString (&pSPI->ProcessName, &AnsiStr, FALSE) != STATUS_SUCCESS)
+ {
+ ERR ("Failed to create Unicode string!\n");
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+
+ pSPI->dwOffset = Len;
+
+ return Ret;
+}
+
+
+/******************************************************************************
+ * Helper for NtQuerySystemInformation
+ */
+static NTSTATUS SnapWalkThreads (HANDLE hSnap, PSYSTEM_PROCESS_INFORMATION pSPI)
+{
+ NTSTATUS Ret = STATUS_SUCCESS;
+ DWORD CurThread = 0;
+ BOOL First = TRUE;
+
+ while (Ret == STATUS_SUCCESS)
+ {
+ SERVER_START_REQ (next_thread)
+ {
+ req->handle = hSnap;
+ req->reset = First;
+ Ret = wine_server_call_err (req);
+ First = FALSE;
+ if (Ret == STATUS_SUCCESS)
+ {
+ PSYSTEM_THREAD_INFORMATION pSTI = &pSPI->ti[CurThread];
+
+ if (reply->pid != pSPI->dwProcessID)
+ continue;
+
+ memset (pSTI, 0, sizeof (pSPI->ti[0]));
+ pSTI->dwOwningPID = (DWORD)reply->pid;
+ pSTI->dwThreadID = (DWORD)reply->tid;
+ pSTI->dwCurrentPriority = reply->base_pri + reply->delta_pri;
+ pSTI->dwBasePriority = reply->base_pri;
+
+ CurThread++;
+ }
+ }
+ SERVER_END_REQ;
+ }
+
+ if (Ret == STATUS_NO_MORE_FILES)
+ Ret = STATUS_SUCCESS;
+
+ return Ret;
+}
+
+
+/******************************************************************************
+ * NtCreateMailslotFile [NTDLL.@]
+ * ZwCreateMailslotFile [NTDLL.@]
+ */
+NTSTATUS WINAPI NtCreateMailslotFile(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8)
+{
+ FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4,x5,x6,x7,x8);
+ return 0;
}
@@ -824,9 +934,9 @@
NTSTATUS result = STATUS_SUCCESS;
- FIXME("(0x%08x,%p,0x%08lx,%p), mostly-stub!\n",
- SystemInformationClass, SystemInformation,
- Length, ResultLength);
+ TRACE ("(0x%08x,%p,0x%08lx,%p)\n",
+ SystemInformationClass, SystemInformation,
+ Length, ResultLength);
/* native checks if the buffer length is 0 before checking if the buffer is NULL
@@ -892,10 +1002,48 @@
break;
- case SystemProcessInformation:
- FIXME("implement the SystemProcessInformation case!\n");
- result = collectProcessInformation(SystemInformation, Length, ResultLength);
+ case SystemProcessInformation: {
+ PSYSTEM_PROCESS_INFORMATION pSPI =
+ (PSYSTEM_PROCESS_INFORMATION)SystemInformation;
+ PSYSTEM_PROCESS_INFORMATION pPrev;
+ HANDLE hSnap = INVALID_HANDLE_VALUE;
+ ULONG InitialLen = Length;
+
+ /* FIXME - Check data alignment & return
+ STATUS_DATATYPE_MISALIGNMENT if necessary */
+
+ FIXME ("SystemProcessInformation class only partially implemented\n");
+
+ if ((result = SnapCreate (&hSnap)) != STATUS_SUCCESS)
+ break;
+
+ /* Iterate over processes */
+ pPrev = pSPI;
+ while ((result = SnapGetNextProcess (hSnap, Length,
+ pSPI)) == STATUS_SUCCESS)
+ {
+ /* Iterate over all threads, and get info on those threads
+ that are in the current process*/
+ if ((result = SnapWalkThreads (hSnap, pSPI)) != STATUS_SUCCESS)
+ break;
+
+ pPrev = pSPI;
+ pSPI = (PSYSTEM_PROCESS_INFORMATION)((char *)pSPI + pSPI->dwOffset);
+ Length -= pPrev->dwOffset;
+ }
+
+ /* Clean up snapshot */
+ NtClose (hSnap);
+ pPrev->dwOffset = 0;
+
+ if (result == STATUS_NO_MORE_FILES)
+ result = STATUS_SUCCESS;
+
+ if ((result == STATUS_SUCCESS) && ResultLength)
+ *ResultLength = InitialLen - Length;
+
break;
+ }
default:
FIXME("(0x%08x,%p,0x%08lx,%p) stub\n",