Index: ntoskrnl/ex/sysinfo.c =================================================================== --- ntoskrnl/ex/sysinfo.c (revision 39187) +++ ntoskrnl/ex/sysinfo.c (working copy) @@ -706,34 +706,104 @@ PEPROCESS Process = NULL, SystemProcess; PETHREAD CurrentThread; ANSI_STRING ImageName; - int CurrentSize, ImageNameLength = 32; // image name len in bytes + int CurrentSize; + USHORT ImageNameMaximumLength; // image name len in bytes + USHORT ImageNameLength; PLIST_ENTRY CurrentEntry; ULONG TotalSize = 0, ThreadsCount; ULONG TotalUser, TotalKernel; PUCHAR Current; NTSTATUS Status = STATUS_SUCCESS; + UNICODE_STRING FileName; + PROS_SECTION_OBJECT SectionObject; + PWCHAR szSrc; _SEH2_TRY { - /* scan the process list */ + /*20090229 Windows first test size. Only after writing to the buffer. + */ + SystemProcess = PsIdleProcess; + Process = SystemProcess; + TotalSize = 0; + do //Debug trace value Windows + { + ThreadsCount = 0; + CurrentEntry = Process->ThreadListHead.Flink; + while (CurrentEntry != &Process->ThreadListHead) + { + ThreadsCount++; + CurrentEntry = CurrentEntry->Flink; + } - PSYSTEM_PROCESS_INFORMATION Spi - = (PSYSTEM_PROCESS_INFORMATION) Buffer; + ImageNameLength = 0; + SectionObject = Process->SectionObject; + if (SectionObject + && SectionObject->FileObject + && SectionObject->FileObject->FileName.Buffer) + { + FileName = SectionObject->FileObject->FileName; + szSrc = (PWCHAR)((PCHAR)FileName.Buffer + FileName.Length); + /* Loop the file name*/ + while (szSrc > FileName.Buffer) + { + if (*--szSrc == OBJ_NAME_PATH_SEPARATOR) + { + szSrc++; + break; + } + else + { + ImageNameLength += sizeof(WCHAR); + } + } + } + if (!ImageNameLength && Process != PsIdleProcess && Process->ImageFileName) + { + ImageNameLength = strlen(Process->ImageFileName) * sizeof(WCHAR); + } + ImageNameMaximumLength = (ImageNameLength > 0 + ? (ImageNameLength / 8 * 8 + ((ImageNameLength % 8) >= 0 ? 1 : 0)*8) + : 0); + // size of the structure for every process + TotalSize += + sizeof(SYSTEM_PROCESS_INFORMATION) + + sizeof(SYSTEM_THREAD_INFORMATION) * ThreadsCount + + ImageNameMaximumLength; - *ReqSize = sizeof(SYSTEM_PROCESS_INFORMATION); + /* Handle idle process entry */ + if (Process == PsIdleProcess) Process = NULL; - if (Size < sizeof(SYSTEM_PROCESS_INFORMATION)) + Process = PsGetNextProcess(Process); + ThreadsCount = 0; + if ((Process == SystemProcess) || (Process == NULL)) + { + break; + } + } while ((Process != SystemProcess) && (Process != NULL)); + + *ReqSize = TotalSize; + + if (Size < *ReqSize || Buffer == NULL) { _SEH2_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small } - RtlZeroMemory(Spi, Size); - SystemProcess = PsIdleProcess; - Process = SystemProcess; - Current = (PUCHAR) Spi; + if (Buffer != NULL) + { + TotalSize = 0; + /* scan the process list */ - do - { + PSYSTEM_PROCESS_INFORMATION Spi + = (PSYSTEM_PROCESS_INFORMATION) Buffer; + + RtlZeroMemory(Spi, Size); + + SystemProcess = PsIdleProcess; + Process = SystemProcess; + Current = (PUCHAR) Spi; + + do + { SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current; ThreadsCount = 0; @@ -746,7 +816,38 @@ // size of the structure for every process CurrentSize = sizeof(SYSTEM_PROCESS_INFORMATION) + sizeof(SYSTEM_THREAD_INFORMATION) * ThreadsCount; - TotalSize += CurrentSize + ImageNameLength; + ImageNameLength = 0; + SectionObject = Process->SectionObject; + szSrc = NULL; + if (SectionObject + && SectionObject->FileObject + && SectionObject->FileObject->FileName.Buffer) + { + FileName = SectionObject->FileObject->FileName; + szSrc = (PWCHAR)((PCHAR)FileName.Buffer + FileName.Length); + /* Loop the file name*/ + while (szSrc > FileName.Buffer) + { + /* Make sure this isn't a backslash */ + if (*--szSrc == OBJ_NAME_PATH_SEPARATOR) + { + szSrc++; + break; + } + else + { + ImageNameLength += sizeof(WCHAR); + } + } + } + if (!ImageNameLength && Process != PsIdleProcess && Process->ImageFileName) + { + ImageNameLength = strlen(Process->ImageFileName) * sizeof(WCHAR); + } + ImageNameMaximumLength = (ImageNameLength > 0 + ? (ImageNameLength / 8 * 8 + ((ImageNameLength % 8) >= 0 ? 1 : 0)*8) + : 0); + TotalSize += CurrentSize + ImageNameMaximumLength; if (TotalSize > Size) { @@ -757,18 +858,25 @@ } // fill system information - SpiCurrent->NextEntryOffset = CurrentSize + ImageNameLength; // relative offset to the beginnnig of the next structure + SpiCurrent->NextEntryOffset = CurrentSize + ImageNameMaximumLength; // relative offset to the beginnnig of the next structure SpiCurrent->NumberOfThreads = ThreadsCount; SpiCurrent->CreateTime = Process->CreateTime; - SpiCurrent->ImageName.Length = strlen(Process->ImageFileName) * sizeof(WCHAR); - SpiCurrent->ImageName.MaximumLength = (USHORT)ImageNameLength; + SpiCurrent->ImageName.Length = ImageNameLength; + SpiCurrent->ImageName.MaximumLength = ImageNameMaximumLength; SpiCurrent->ImageName.Buffer = (void*)(Current + CurrentSize); // copy name to the end of the struct if(Process != PsIdleProcess) { + if (szSrc) + { + RtlCopyMemory(SpiCurrent->ImageName.Buffer, szSrc, SpiCurrent->ImageName.Length); + } + else if (Process->ImageFileName) + { RtlInitAnsiString(&ImageName, Process->ImageFileName); RtlAnsiStringToUnicodeString(&SpiCurrent->ImageName, &ImageName, FALSE); + } } else { @@ -831,12 +939,13 @@ break; } else - Current += CurrentSize + ImageNameLength; - } while ((Process != SystemProcess) && (Process != NULL)); + Current += CurrentSize + ImageNameMaximumLength; + } while ((Process != SystemProcess) && (Process != NULL)); - if(Process != NULL) + if(Process != NULL) ObDereferenceObject(Process); - Status = STATUS_SUCCESS; + Status = STATUS_SUCCESS; + } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {