Implementation of CreationTime and ExitTime for GetProcessTimes / NtQueryInformationProcess

Stefan Siebert stefan.siebert at web.de
Thu Jul 20 08:09:54 CDT 2006


This patch fixes The Notes Client bug 2985 
<http://bugs.winehq.org/show_bug.cgi?id=2985> and it's duplicates 3294 
<http://bugs.winehq.org/show_bug.cgi?id=3294> and 5686 
<http://bugs.winehq.org/show_bug.cgi?id=5686> (process id has been reused).
An explanation of the problem itself (internals) can be found in bugzilla.

The fix has been extensively tested and the test case follows.

Changelog: Implementation of CreationTime and ExitTime for 
GetProcessTimes  / NtQueryInformationProcess
-------------- next part --------------
? getprocesstimes.diff
Index: dlls/kernel/time.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/time.c,v
retrieving revision 1.60
diff -u -p -r1.60 time.c
--- dlls/kernel/time.c	23 May 2006 12:48:03 -0000	1.60
+++ dlls/kernel/time.c	20 Jul 2006 12:44:17 -0000
@@ -575,16 +575,21 @@ static void TIME_ClockTimeToFileTime(clo
  *  Also, there is a need to separate times used by different applications.
  *
  * BUGS
- *  lpCreationTime and lpExitTime are not initialised in the Wine implementation.
+ *  KernelTime and UserTime are always for the current process
  */
 BOOL WINAPI GetProcessTimes( HANDLE hprocess, LPFILETIME lpCreationTime,
     LPFILETIME lpExitTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime )
 {
     struct tms tms;
+    KERNEL_USER_TIMES pti;
 
     times(&tms);
     TIME_ClockTimeToFileTime(tms.tms_utime,lpUserTime);
     TIME_ClockTimeToFileTime(tms.tms_stime,lpKernelTime);
+    if (NtQueryInformationProcess( hprocess, ProcessTimes, &pti, sizeof(pti), NULL))
+        return FALSE;
+    LL2FILETIME( pti.CreateTime.QuadPart, lpCreationTime);
+    LL2FILETIME( pti.ExitTime.QuadPart, lpExitTime);
     return TRUE;
 }
 
Index: dlls/ntdll/ntdll_misc.h
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/ntdll_misc.h,v
retrieving revision 1.82
diff -u -p -r1.82 ntdll_misc.h
--- dlls/ntdll/ntdll_misc.h	23 May 2006 12:48:22 -0000	1.82
+++ dlls/ntdll/ntdll_misc.h	20 Jul 2006 12:44:17 -0000
@@ -39,11 +39,15 @@ extern void set_cpu_context( const CONTE
 extern LPCSTR debugstr_us( const UNICODE_STRING *str );
 extern void dump_ObjectAttributes (const OBJECT_ATTRIBUTES *ObjectAttributes);
 
+
 extern void NTDLL_get_server_timeout( abs_time_t *when, const LARGE_INTEGER *timeout );
 extern void NTDLL_from_server_timeout( LARGE_INTEGER *timeout, const abs_time_t *when );
 extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UINT flags,
                                                  const LARGE_INTEGER *timeout, HANDLE signal_object );
 
+/* time conversion */
+extern void NTDLL_convert_abstime_linteger( LARGE_INTEGER *timeout, const abs_time_t *when );
+
 /* init routines */
 extern BOOL SIGNAL_Init(void);
 extern size_t get_signal_stack_total_size(void);
Index: dlls/ntdll/process.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/process.c,v
retrieving revision 1.17
diff -u -p -r1.17 process.c
--- dlls/ntdll/process.c	23 May 2006 12:48:22 -0000	1.17
+++ dlls/ntdll/process.c	20 Jul 2006 12:44:18 -0000
@@ -219,6 +219,8 @@ NTSTATUS WINAPI NtQueryInformationProces
     case ProcessTimes:
         {
             KERNEL_USER_TIMES pti;
+            abs_time_t start_time;
+            abs_time_t end_time;
 
             if (ProcessInformationLength >= sizeof(KERNEL_USER_TIMES))
             {
@@ -228,9 +230,25 @@ NTSTATUS WINAPI NtQueryInformationProces
                     ret = STATUS_INVALID_HANDLE;
                 else
                 {
-                    /* FIXME : real data */
+                    /* FIXME : User- and KernelTime have to be implemented */
                     memset(&pti, 0, sizeof(KERNEL_USER_TIMES));
 
+                    SERVER_START_REQ(get_process_info)
+                    {
+                      req->handle = ProcessHandle;
+                      if ((ret = wine_server_call( req )) == STATUS_SUCCESS)
+                      {
+                        start_time.sec = reply->start_time.sec;
+                        start_time.usec = reply->start_time.usec;
+                        end_time.sec = reply->end_time.sec;
+                        end_time.usec = reply->end_time.usec;
+                      }
+                    }
+                    SERVER_END_REQ;
+
+                    NTDLL_convert_abstime_linteger(&pti.CreateTime, &start_time);
+                    NTDLL_convert_abstime_linteger(&pti.ExitTime, &end_time);
+
                     memcpy(ProcessInformation, &pti, sizeof(KERNEL_USER_TIMES));
 
                     len = sizeof(KERNEL_USER_TIMES);
Index: dlls/ntdll/time.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/time.c,v
retrieving revision 1.87
diff -u -p -r1.87 time.c
--- dlls/ntdll/time.c	26 Jun 2006 12:15:22 -0000	1.87
+++ dlls/ntdll/time.c	20 Jul 2006 12:44:18 -0000
@@ -494,6 +494,16 @@ void NTDLL_from_server_timeout( LARGE_IN
     timeout->QuadPart += when->usec * 10;
 }
 
+/***********************************************************************
+ *              NTDLL_convert_abstime_linteger
+ *
+ * Convert an abs_time_t struct from the server into a time
+ */
+void NTDLL_convert_abstime_linteger( LARGE_INTEGER *time, const abs_time_t *abs_time )
+{
+  time->QuadPart = abs_time->sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970;
+  time->QuadPart += abs_time->usec * 10;
+}
 
 /******************************************************************************
  *       RtlTimeToTimeFields [NTDLL.@]
Index: include/wine/server_protocol.h
===================================================================
RCS file: /home/wine/wine/include/wine/server_protocol.h,v
retrieving revision 1.202
diff -u -p -r1.202 server_protocol.h
--- include/wine/server_protocol.h	19 Jul 2006 17:33:09 -0000	1.202
+++ include/wine/server_protocol.h	20 Jul 2006 12:44:22 -0000
@@ -347,6 +347,8 @@ struct get_process_info_reply
     int          priority;
     int          affinity;
     void*        peb;
+    abs_time_t   start_time;
+    abs_time_t   end_time;
 };
 
 
@@ -4383,6 +4385,6 @@ union generic_reply
     struct query_symlink_reply query_symlink_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 238
+#define SERVER_PROTOCOL_VERSION 3
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
Index: server/process.c
===================================================================
RCS file: /home/wine/wine/server/process.c,v
retrieving revision 1.169
diff -u -p -r1.169 process.c
--- server/process.c	19 Jul 2006 17:33:09 -0000	1.169
+++ server/process.c	20 Jul 2006 12:44:23 -0000
@@ -924,6 +924,10 @@ DECL_HANDLER(get_process_info)
         reply->priority         = process->priority;
         reply->affinity         = process->affinity;
         reply->peb              = process->peb;
+        reply->start_time.sec   = process->start_time.tv_sec;
+        reply->start_time.usec  = process->start_time.tv_usec;
+        reply->end_time.sec     = process->end_time.tv_sec;
+        reply->end_time.usec    = process->end_time.tv_usec;
         release_object( process );
     }
 }
Index: server/protocol.def
===================================================================
RCS file: /home/wine/wine/server/protocol.def,v
retrieving revision 1.202
diff -u -p -r1.202 protocol.def
--- server/protocol.def	19 Jul 2006 17:33:09 -0000	1.202
+++ server/protocol.def	20 Jul 2006 12:44:25 -0000
@@ -317,6 +317,8 @@ struct token_groups
     int          priority;         /* priority class */
     int          affinity;         /* process affinity mask */
     void*        peb;              /* PEB address in process address space */
+    abs_time_t   start_time;       /* process start time */
+    abs_time_t   end_time;         /* process end time */
 @END
 
 
Index: server/trace.c
===================================================================
RCS file: /home/wine/wine/server/trace.c,v
retrieving revision 1.316
diff -u -p -r1.316 trace.c
--- server/trace.c	19 Jul 2006 17:33:09 -0000	1.316
+++ server/trace.c	20 Jul 2006 12:44:27 -0000
@@ -737,7 +737,12 @@ static void dump_get_process_info_reply(
     fprintf( stderr, " exit_code=%d,", req->exit_code );
     fprintf( stderr, " priority=%d,", req->priority );
     fprintf( stderr, " affinity=%d,", req->affinity );
-    fprintf( stderr, " peb=%p", req->peb );
+    fprintf( stderr, " peb=%p,", req->peb );
+    fprintf( stderr, " start_time=" );
+    dump_abs_time( &req->start_time );
+    fprintf( stderr, "," );
+    fprintf( stderr, " end_time=" );
+    dump_abs_time( &req->end_time );
 }
 
 static void dump_set_process_info_request( const struct set_process_info_request *req )


More information about the wine-patches mailing list