Leaked source code of windows server 2003
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.

246 lines
5.6 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. if (p->Buffer == NULL || p->Length == 0) {
  68. goto SkipInit;
  69. }
  70. }
  71. Status = RtlUnicodeStringToAnsiString( &AnsiString, p, TRUE );
  72. if (! NT_SUCCESS(Status)) {
  73. goto SkipInit;
  74. }
  75. s = AnsiString.Buffer;
  76. n = AnsiString.Length;
  77. while (*s) {
  78. //
  79. // Skip over any white space.
  80. //
  81. while (*s && *s <= ' ') {
  82. s++;
  83. }
  84. //
  85. // Copy token to next white space separator and null terminate
  86. //
  87. if (*s) {
  88. NumberOfArgPointers++;
  89. while (*s > ' ') {
  90. s++;
  91. }
  92. }
  93. }
  94. RtlFreeAnsiString(&AnsiString);
  95. NumberOfArgPointers++;
  96. ws = ProcessParameters->Environment;
  97. if (ws != NULL) {
  98. while (*ws) {
  99. NumberOfEnvPointers++;
  100. while (*ws++) {
  101. ;
  102. }
  103. }
  104. }
  105. NumberOfEnvPointers++;
  106. }
  107. //
  108. // both counters also have a trailing pointer to NULL, so count this twice for each
  109. //
  110. TotalNumberOfPointers = NumberOfArgPointers + NumberOfEnvPointers + 4;
  111. if (ARGUMENT_PRESENT( ProcessParameters )) {
  112. DebugParameter = ProcessParameters->DebugFlags;
  113. NtCurrentTeb()->LastStatusValue = STATUS_SUCCESS;
  114. dst = RtlAllocateHeap( Peb->ProcessHeap, 0, TotalNumberOfPointers * sizeof( PCH ) );
  115. if (! dst) {
  116. Status = NtCurrentTeb()->LastStatusValue;
  117. if (NT_SUCCESS(Status)) {
  118. Status = STATUS_NO_MEMORY;
  119. }
  120. goto SkipInit;
  121. }
  122. argv = dst;
  123. *dst = NULL;
  124. //
  125. // Now extract the arguments from the process command line.
  126. // using whitespace as separator characters.
  127. //
  128. p = &ProcessParameters->CommandLine;
  129. if (p->Buffer == NULL || p->Length == 0) {
  130. p = &ProcessParameters->ImagePathName;
  131. if (p->Buffer == NULL || p->Length == 0) {
  132. goto SkipInit;
  133. }
  134. }
  135. Status = RtlUnicodeStringToAnsiString( &AnsiString, p, TRUE );
  136. if (! NT_SUCCESS(Status)) {
  137. goto SkipInit;
  138. }
  139. s = AnsiString.Buffer;
  140. n = AnsiString.Length;
  141. NtCurrentTeb()->LastStatusValue = STATUS_SUCCESS;
  142. d = RtlAllocateHeap( Peb->ProcessHeap, 0, n+2 );
  143. if (! d) {
  144. Status = NtCurrentTeb()->LastStatusValue;
  145. if (NT_SUCCESS(Status)) {
  146. Status = STATUS_NO_MEMORY;
  147. }
  148. RtlFreeAnsiString (&AnsiString);
  149. goto SkipInit;
  150. }
  151. while (*s) {
  152. //
  153. // Skip over any white space.
  154. //
  155. while (*s && *s <= ' ') {
  156. s++;
  157. }
  158. //
  159. // Copy token to next white space separator and null terminate
  160. //
  161. if (*s) {
  162. *dst++ = d;
  163. argc++;
  164. while (*s > ' ') {
  165. *d++ = *s++;
  166. }
  167. *d++ = '\0';
  168. }
  169. }
  170. *dst++ = NULL;
  171. RtlFreeAnsiString (&AnsiString);
  172. envp = dst;
  173. ws = ProcessParameters->Environment;
  174. if (ws != NULL) {
  175. while (*ws) {
  176. *dst++ = (char *)ws;
  177. while (*ws++) {
  178. ;
  179. }
  180. }
  181. }
  182. *dst++ = NULL;
  183. }
  184. SkipInit:
  185. if (DebugParameter != 0) {
  186. DbgBreakPoint();
  187. }
  188. if (NT_SUCCESS(Status)) {
  189. Status = main( argc, argv, envp, DebugParameter );
  190. }
  191. NtTerminateProcess( NtCurrentProcess(), Status );
  192. }