Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
5.2 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. startup.c
  5. Abstract:
  6. This module contains the startup code for an NT Application
  7. Author:
  8. Steve Wood (stevewo) 22-Aug-1989
  9. Environment:
  10. User Mode only
  11. Revision History:
  12. --*/
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. //
  17. // User mode process entry point.
  18. //
  19. int
  20. __cdecl
  21. main(
  22. int argc,
  23. char *argv[],
  24. char *envp[],
  25. ULONG DebugParameter OPTIONAL
  26. );
  27. VOID
  28. NtProcessStartup(
  29. PPEB Peb
  30. )
  31. {
  32. int argc;
  33. char **argv;
  34. char **envp;
  35. char **dst;
  36. char *nullPtr = NULL;
  37. PCH s, d;
  38. LPWSTR ws,wd;
  39. ULONG n, DebugParameter;
  40. PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
  41. PUNICODE_STRING p;
  42. ANSI_STRING AnsiString;
  43. ULONG NumberOfArgPointers;
  44. ULONG NumberOfEnvPointers;
  45. ULONG TotalNumberOfPointers;
  46. NTSTATUS Status;
  47. ASSERT( Peb != NULL );
  48. ProcessParameters = RtlNormalizeProcessParams( Peb->ProcessParameters );
  49. DebugParameter = 0;
  50. argc = 0;
  51. argv = &nullPtr;
  52. envp = &nullPtr;
  53. NumberOfEnvPointers = 1;
  54. NumberOfArgPointers = 1;
  55. Status = STATUS_SUCCESS;
  56. if (ARGUMENT_PRESENT( ProcessParameters )) {
  57. //
  58. // Compute how many pointers are needed to pass argv[] and envp[]
  59. //
  60. //
  61. // Now extract the arguments from the process command line.
  62. // using whitespace as separator characters.
  63. //
  64. p = &ProcessParameters->CommandLine;
  65. if (p->Buffer == NULL || p->Length == 0) {
  66. p = &ProcessParameters->ImagePathName;
  67. }
  68. RtlUnicodeStringToAnsiString( &AnsiString, p, TRUE );
  69. s = AnsiString.Buffer;
  70. n = AnsiString.Length;
  71. if (s != NULL) {
  72. while (*s) {
  73. //
  74. // Skip over any white space.
  75. //
  76. while (*s && *s <= ' ') {
  77. s++;
  78. }
  79. //
  80. // Copy token to next white space separator and null terminate
  81. //
  82. if (*s) {
  83. NumberOfArgPointers++;
  84. while (*s > ' ') {
  85. s++;
  86. }
  87. }
  88. }
  89. }
  90. NumberOfArgPointers++;
  91. ws = ProcessParameters->Environment;
  92. if (ws != NULL) {
  93. while (*ws) {
  94. NumberOfEnvPointers++;
  95. while (*ws++) {
  96. ;
  97. }
  98. }
  99. }
  100. NumberOfEnvPointers++;
  101. }
  102. //
  103. // both counters also have a trailing pointer to NULL, so count this twice for each
  104. //
  105. TotalNumberOfPointers = NumberOfArgPointers + NumberOfEnvPointers + 4;
  106. if (ARGUMENT_PRESENT( ProcessParameters )) {
  107. DebugParameter = ProcessParameters->DebugFlags;
  108. NtCurrentTeb()->LastStatusValue = STATUS_SUCCESS;
  109. dst = RtlAllocateHeap( Peb->ProcessHeap, 0, TotalNumberOfPointers * sizeof( PCH ) );
  110. if (! dst) {
  111. Status = NtCurrentTeb()->LastStatusValue;
  112. if (NT_SUCCESS(Status)) {
  113. Status = STATUS_NO_MEMORY;
  114. }
  115. goto InitFailed;
  116. }
  117. argv = dst;
  118. *dst = NULL;
  119. //
  120. // Now extract the arguments from the process command line.
  121. // using whitespace as separator characters.
  122. //
  123. p = &ProcessParameters->CommandLine;
  124. if (p->Buffer == NULL || p->Length == 0) {
  125. p = &ProcessParameters->ImagePathName;
  126. }
  127. RtlUnicodeStringToAnsiString( &AnsiString, p, TRUE );
  128. s = AnsiString.Buffer;
  129. n = AnsiString.Length;
  130. if (s != NULL) {
  131. NtCurrentTeb()->LastStatusValue = STATUS_SUCCESS;
  132. d = RtlAllocateHeap( Peb->ProcessHeap, 0, n+2 );
  133. if (! d) {
  134. Status = NtCurrentTeb()->LastStatusValue;
  135. if (NT_SUCCESS(Status)) {
  136. Status = STATUS_NO_MEMORY;
  137. }
  138. goto InitFailed;
  139. }
  140. while (*s) {
  141. //
  142. // Skip over any white space.
  143. //
  144. while (*s && *s <= ' ') {
  145. s++;
  146. }
  147. //
  148. // Copy token to next white space separator and null terminate
  149. //
  150. if (*s) {
  151. *dst++ = d;
  152. argc++;
  153. while (*s > ' ') {
  154. *d++ = *s++;
  155. }
  156. *d++ = '\0';
  157. }
  158. }
  159. }
  160. *dst++ = NULL;
  161. envp = dst;
  162. ws = ProcessParameters->Environment;
  163. if (ws != NULL) {
  164. while (*ws) {
  165. *dst++ = (char *)ws;
  166. while (*ws++) {
  167. ;
  168. }
  169. }
  170. }
  171. *dst++ = NULL;
  172. }
  173. InitFailed:
  174. if (DebugParameter != 0) {
  175. DbgBreakPoint();
  176. }
  177. if (NT_SUCCESS(Status)) {
  178. Status = main( argc, argv, envp, DebugParameter );
  179. }
  180. NtTerminateProcess( NtCurrentProcess(), Status );
  181. }