Guest User

Untitled

a guest
Aug 16th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.06 KB | None | 0 0
  1. /*
  2. * FILE: tools/nci/ncitool.c
  3. * COPYRIGHT: See COPYING in the top level directory
  4. * PROJECT: Native Call Interface Support Tool
  5. * PURPOSE: Generates NCI Tables and Stubs.
  6. * PROGRAMMER; Alex Ionescu (alex@relsoft.net)
  7. * CHANGE HISTORY: 14/01/05 - Created. Based on original code by
  8. * KJK::Hyperion and Emanuelle Aliberti.
  9. *
  10. */
  11.  
  12. /* INCLUDE ******************************************************************/
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #if !defined(__FreeBSD__) && !defined(__APPLE__)
  18. # include <malloc.h>
  19. #endif // __FreeBSD__
  20.  
  21. /* DEFINES ****************************************************************/
  22.  
  23. #define INPUT_BUFFER_SIZE 255
  24. #define Arguments 8
  25.  
  26. /******* Table Indexes ************/
  27. #define MAIN_INDEX 0x0
  28. #define WIN32K_INDEX 0x1000
  29.  
  30. /******* Argument List ************/
  31. /* Databases */
  32. #define NativeSystemDb 0
  33. #define NativeGuiDb 1
  34.  
  35. /* Service Tables */
  36. #define NtosServiceTable 2
  37. #define Win32kServiceTable 3
  38.  
  39. /* Stub Files */
  40. #define NtosUserStubs 4
  41. #define NtosKernelStubs 5
  42. #define Win32kStubs 6
  43.  
  44. /* Spec Files */
  45. #define NtSpec 7
  46.  
  47. /********** Stub Code ************/
  48.  
  49. /*
  50. * This stubs calls into KUSER_SHARED_DATA where either a
  51. * sysenter or interrupt is performed, depending on CPU support.
  52. */
  53. #define UserModeStub_x86 " mov eax, %d\n" \
  54. " mov ecx, KUSER_SHARED_SYSCALL\n" \
  55. " call dword ptr [ecx]\n" \
  56. " ret %d\n\n"
  57.  
  58. #define UserModeStub_amd64 " mov eax, %d\n" \
  59. " mov r10, rcx\n" \
  60. " syscall\n" \
  61. " ret %d\n\n"
  62.  
  63. #define UserModeStub_ppc " stwu 1,-16(1)\n" \
  64. " mflr 0\n\t" \
  65. " stw 0,0(1)\n" \
  66. " li 0,0x%x\n" \
  67. " sc\n" \
  68. " lwz 0,0(1)\n" \
  69. " mtlr 0\n" \
  70. " addi 1,1,16\n" \
  71. " blr\n"
  72.  
  73. #define UserModeStub_mips " li $8, KUSER_SHARED_SYSCALL\n" \
  74. " lw $8,0($8)\n" \
  75. " j $8\n" \
  76. " nop\n"
  77.  
  78. #define UserModeStub_arm " swi #0x%x\n" \
  79. " bx lr\n\n"
  80.  
  81.  
  82. /*
  83. * This stub calls KiSystemService directly with a fake INT2E stack.
  84. * Because EIP is pushed during the call, the handler will return here.
  85. */
  86. #define KernelModeStub_x86 " mov eax, %d\n" \
  87. " lea edx, [esp + 4]\n" \
  88. " pushf\n" \
  89. " push KGDT_R0_CODE\n" \
  90. " call _KiSystemService\n" \
  91. " ret %d\n\n"
  92.  
  93. #define KernelModeStub_amd64 " mov eax, %d\n" \
  94. " call KiSystemService\n" \
  95. " ret %d\n\n"
  96.  
  97. /* For now, use the usermode stub. We'll optimize later */
  98. #define KernelModeStub_ppc UserModeStub_ppc
  99.  
  100. #define KernelModeStub_mips " j KiSystemService\n" \
  101. " nop\n"
  102.  
  103. #define KernelModeStub_arm " mov ip, lr\n" \
  104. " swi #0x%x\n" \
  105. " bx ip\n\n"
  106.  
  107. /***** Arch Dependent Stuff ******/
  108. struct ncitool_data_t {
  109. const char *arch;
  110. int args_to_bytes;
  111. const char *km_stub;
  112. const char *um_stub;
  113. const char *global_header;
  114. const char *declaration;
  115. };
  116.  
  117. struct ncitool_data_t ncitool_data[] = {
  118. { "i386", 4, KernelModeStub_x86, UserModeStub_x86,
  119. "PUBLIC _%s@%d\n", "_%s@%d:\n" },
  120. { "amd64", 4, KernelModeStub_amd64, UserModeStub_amd64,
  121. "PUBLIC %s\n", "%s:\n" },
  122. { "powerpc", 4, KernelModeStub_ppc, UserModeStub_ppc,
  123. "\t.globl %s\n", "%s:\n" },
  124. { "mips", 4, KernelModeStub_mips, UserModeStub_mips,
  125. "\t.globl %s\n", "%s:\n" },
  126. { "arm", 4, KernelModeStub_arm, UserModeStub_arm,
  127. "\t.globl %s\n", "%s:\n" },
  128. { 0, }
  129. };
  130. int arch_sel = 0;
  131. #define ARGS_TO_BYTES(x) (x)*(ncitool_data[arch_sel].args_to_bytes)
  132. #define UserModeStub ncitool_data[arch_sel].um_stub
  133. #define KernelModeStub ncitool_data[arch_sel].km_stub
  134. #define GlobalHeader ncitool_data[arch_sel].global_header
  135. #define Declaration ncitool_data[arch_sel].declaration
  136.  
  137. /* FUNCTIONS ****************************************************************/
  138.  
  139. /*++
  140. * WriteFileHeader
  141. *
  142. * Prints out the File Header for a Stub File.
  143. *
  144. * Params:
  145. * StubFile - Stub File to which to write the header.
  146. *
  147. * FileDescription - Description of the Stub file to which to write the header.
  148. *
  149. * FileLocation - Name of the Stub file to which to write the header.
  150. *
  151. * Returns:
  152. * None.
  153. *
  154. * Remarks:
  155. * FileLocation is only used for printing the header.
  156. *
  157. *--*/
  158. void
  159. WriteFileHeader(FILE * StubFile,
  160. char* FileDescription,
  161. char* FileLocation)
  162. {
  163. /* This prints out the file header */
  164. fprintf(StubFile,
  165. "/* FILE: %s\n"
  166. " * COPYRIGHT: See COPYING in the top level directory\n"
  167. " * PURPOSE: %s\n"
  168. " * PROGRAMMER: Computer Generated File. See tools/nci/ncitool.c\n"
  169. " * REMARK: DO NOT EDIT OR COMMIT MODIFICATIONS TO THIS FILE\n"
  170. " */\n\n\n"
  171. "#ifdef __ASM__\n"
  172. "#include <reactos/asm.h>\n"
  173. ".code\n",
  174. "#endif\n"
  175. "#include <ndk/asm.h>\n\n"
  176.  
  177. FileDescription,
  178. FileLocation);
  179. }
  180.  
  181. /*++
  182. * WriteFileHeader
  183. *
  184. * Prints out the File Header for a Stub File.
  185. *
  186. * Params:
  187. * StubFile - Stub File to which to write the header.
  188. *
  189. * FileDescription - Description of the Stub file to which to write the header.
  190. *
  191. * FileLocation - Name of the Stub file to which to write the header.
  192. *
  193. * Returns:
  194. * None.
  195. *
  196. * Remarks:
  197. * FileLocation is only used for printing the header.
  198. *
  199. *--*/
  200. void
  201. WriteStubHeader(FILE* StubFile,
  202. char* SyscallName,
  203. unsigned StackBytes)
  204. {
  205. /* Export the function */
  206. fprintf(StubFile, GlobalHeader, SyscallName, StackBytes);
  207.  
  208. /* Define it */
  209. fprintf(StubFile, Declaration, SyscallName, StackBytes);
  210. }
  211.  
  212.  
  213. /*++
  214. * WriteKernelModeStub
  215. *
  216. * Prints out the Kernel Mode Stub for a System Call.
  217. *
  218. * Params:
  219. * StubFile - Stub File to which to write the header.
  220. *
  221. * SyscallName - Name of System Call for which to add the stub.
  222. *
  223. * StackBytes - Number of bytes on the stack to return after doing the system call.
  224. *
  225. * SyscallId - Service Descriptor Table ID for this System Call.
  226. *
  227. * Returns:
  228. * None.
  229. *
  230. * Remarks:
  231. * On i386, StackBytes is the number of arguments x 4.
  232. *
  233. *--*/
  234. void
  235. WriteKernelModeStub(FILE* StubFile,
  236. char* SyscallName,
  237. unsigned StackBytes,
  238. unsigned int SyscallId)
  239. {
  240. /* Write the Stub Header and export the Function */
  241. WriteStubHeader(StubFile, SyscallName, StackBytes);
  242.  
  243. /* Write the Stub Code */
  244. fprintf(StubFile, KernelModeStub, SyscallId, StackBytes);
  245. }
  246.  
  247. /*++
  248. * WriteUserModeStub
  249. *
  250. * Prints out the User Mode Stub for a System Call.
  251. *
  252. * Params:
  253. * StubFile - Stub File to which to write the header.
  254. *
  255. * SyscallName - Name of System Call for which to add the stub.
  256. *
  257. * StackBytes - Number of bytes on the stack to return after doing the system call.
  258. *
  259. * SyscallId - Service Descriptor Table ID for this System Call.
  260. *
  261. * Returns:
  262. * None.
  263. *
  264. * Remarks:
  265. * On i386, StackBytes is the number of arguments x 4.
  266. *
  267. *--*/
  268. void
  269. WriteUserModeStub(FILE* StubFile,
  270. char* SyscallName,
  271. unsigned StackBytes,
  272. unsigned int SyscallId)
  273. {
  274. /* Write the Stub Header and export the Function */
  275. WriteStubHeader(StubFile, SyscallName, StackBytes);
  276.  
  277. /* Write the Stub Code */
  278. fprintf(StubFile, UserModeStub, SyscallId, StackBytes);
  279. }
  280.  
  281. /*++
  282. * GetNameAndArgumentsFromDb
  283. *
  284. * Parses an entry from a System Call Database, extracting
  285. * the function's name and arguments that it takes.
  286. *
  287. * Params:
  288. * Line - Entry from the Database to parse.
  289. *
  290. * NtSyscallName - Output string to which to save the Function Name
  291. *
  292. * SyscallArguments - Output string to which to save the number of
  293. * arguments that the function takes.
  294. *
  295. * Returns:
  296. * None.
  297. *
  298. * Remarks:
  299. * On i386, StackBytes is the number of arguments x 4.
  300. *
  301. *--*/
  302. void
  303. GetNameAndArgumentsFromDb(char Line[],
  304. char ** NtSyscallName,
  305. char ** SyscallArguments)
  306. {
  307. char *s;
  308. char *stmp;
  309.  
  310. /* Remove new line */
  311. if ((s = (char *) strchr(Line,'\r')) != NULL) {
  312. *s = '\0';
  313. }
  314.  
  315. /* Skip comments (#) and empty lines */
  316. s = &Line[0];
  317. if ((*s) != '#' && (*s) != '\0') {
  318.  
  319. /* Extract the NtXXX name */
  320. *NtSyscallName = (char *)strtok(s," \t");
  321.  
  322. /* Extract the argument count */
  323. *SyscallArguments = (char *)strtok(NULL," \t");
  324.  
  325. /* Remove, if present, the trailing LF */
  326. if ((stmp = strchr(*SyscallArguments, '\n')) != NULL) {
  327. *stmp = '\0';
  328. }
  329.  
  330. } else {
  331.  
  332. /* Skip this entry */
  333. *NtSyscallName = NULL;
  334. *SyscallArguments = NULL;
  335. }
  336. }
  337.  
  338. /*++
  339. * CreateStubs
  340. *
  341. * Parses a System Call Database and creates stubs for all the entries.
  342. *
  343. * Params:
  344. * SyscallDb - System Call Database to parse.
  345. *
  346. * UserModeFiles - Array of Usermode Stub Files to which to write the stubs.
  347. *
  348. * KernelModeFile - Kernelmode Stub Files to which to write the stubs.
  349. *
  350. * Index - Number of first syscall
  351. *
  352. * UserFiles - Number of Usermode Stub Files to create
  353. *
  354. * NeedsZw - Write Zw prefix?
  355. *
  356. * Returns:
  357. * None.
  358. *
  359. * Remarks:
  360. * None.
  361. *
  362. *--*/
  363. void
  364. CreateStubs(FILE * SyscallDb,
  365. FILE * UserModeFiles[],
  366. FILE * KernelModeFile,
  367. unsigned Index,
  368. unsigned UserFiles,
  369. unsigned NeedsZw)
  370. {
  371. char Line[INPUT_BUFFER_SIZE];
  372. char *NtSyscallName;
  373. char *SyscallArguments;
  374. int SyscallId;
  375. unsigned StackBytes;
  376. unsigned int i;
  377.  
  378. /* We loop, incrementing the System Call Index, until the end of the file */
  379. for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) {
  380.  
  381. /* Extract the Name and Arguments */
  382. GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments);
  383. if (SyscallArguments != NULL)
  384. StackBytes = ARGS_TO_BYTES(strtoul(SyscallArguments, NULL, 0));
  385. else
  386. StackBytes = 0;
  387.  
  388. /* Make sure we really extracted something */
  389. if (NtSyscallName) {
  390.  
  391. /* Create Usermode Stubs for Nt/Zw syscalls in each Usermode file */
  392. for (i= 0; i < UserFiles; i++) {
  393.  
  394. /* Write the Stub Header and export the Function */
  395. WriteStubHeader(UserModeFiles[i], NtSyscallName, StackBytes);
  396.  
  397. /* If a Zw Version is needed (was specified), write it too */
  398. if (NeedsZw) {
  399.  
  400. NtSyscallName[0] = 'Z';
  401. NtSyscallName[1] = 'w';
  402.  
  403. /* Write the Stub Header and export the Function */
  404. WriteStubHeader(UserModeFiles[i], NtSyscallName, StackBytes);
  405. }
  406.  
  407. /* Write the Stub Code */
  408. fprintf(UserModeFiles[i], UserModeStub, SyscallId | Index, StackBytes);
  409. }
  410.  
  411. /* Create the Kernel coutnerparts (only Zw*, Nt* are the real functions!) */
  412. if (KernelModeFile) {
  413.  
  414. NtSyscallName[0] = 'Z';
  415. NtSyscallName[1] = 'w';
  416. WriteKernelModeStub(KernelModeFile,
  417. NtSyscallName,
  418. StackBytes,
  419. SyscallId | Index);
  420. }
  421.  
  422. /* Only increase if we actually added something */
  423. SyscallId++;
  424. }
  425. }
  426.  
  427. #if defined(_MSC_VER)
  428. for (i= 0; i < UserFiles; i++) fprintf(UserModeFiles[i], "END\n");
  429. fprintf(KernelModeFile, "END\n");
  430. #endif
  431. }
  432.  
  433. /*++
  434. * CreateSystemServiceTable
  435. *
  436. * Parses a System Call Database and creates a System Call Service Table for it.
  437. *
  438. * Params:
  439. * SyscallDb - System Call Database to parse.
  440. *
  441. * SyscallTable - File in where to create System Call Service Table.
  442. *
  443. * Name - Name of the Service Table.
  444. *
  445. * FileLocation - Filename containing the Table.
  446. *
  447. * Returns:
  448. * None.
  449. *
  450. * Remarks:
  451. * FileLocation is only used for the header generation.
  452. *
  453. *--*/
  454. void
  455. CreateSystemServiceTable(FILE *SyscallDb,
  456. FILE *SyscallTable,
  457. char * Name,
  458. char * FileLocation)
  459. {
  460. char Line[INPUT_BUFFER_SIZE];
  461. char *NtSyscallName;
  462. char *SyscallArguments;
  463. int SyscallId;
  464.  
  465. /* Print the Header */
  466. WriteFileHeader(SyscallTable, "System Call Table for Native API", FileLocation);
  467.  
  468. /* First we build the SSDT */
  469. fprintf(SyscallTable,"\n\n\n");
  470. fprintf(SyscallTable,"ULONG_PTR %sSSDT[] = {\n", Name);
  471.  
  472. /* We loop, incrementing the System Call Index, until the end of the file */
  473. for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) {
  474.  
  475. /* Extract the Name and Arguments */
  476. GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments);
  477.  
  478. /* Make sure we really extracted something */
  479. if (NtSyscallName) {
  480.  
  481. /* Add a new line */
  482. if (SyscallId > 0) fprintf(SyscallTable,",\n");
  483.  
  484. /* Write the syscall name in the service table. */
  485. fprintf(SyscallTable,"\t\t(ULONG_PTR)%s", NtSyscallName);
  486.  
  487. /* Only increase if we actually added something */
  488. SyscallId++;
  489. }
  490. }
  491.  
  492. /* Close the service table (C syntax) */
  493. fprintf(SyscallTable,"\n};\n");
  494.  
  495. /* Now we build the SSPT */
  496. rewind(SyscallDb);
  497. fprintf(SyscallTable,"\n\n\n");
  498. fprintf(SyscallTable,"UCHAR %sSSPT[] = {\n", Name);
  499.  
  500. for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) {
  501.  
  502. /* Extract the Name and Arguments */
  503. GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments);
  504.  
  505. /* Make sure we really extracted something */
  506. if (NtSyscallName) {
  507.  
  508. /* Add a new line */
  509. if (SyscallId > 0) fprintf(SyscallTable,",\n");
  510.  
  511. /* Write the syscall arguments in the argument table. */
  512. if (SyscallArguments != NULL)
  513. fprintf(SyscallTable,"\t\t%lu * sizeof(void *)",strtoul(SyscallArguments, NULL, 0));
  514. else
  515. fprintf(SyscallTable,"\t\t0");
  516.  
  517. /* Only increase if we actually added something */
  518. SyscallId++;
  519. }
  520. }
  521.  
  522. /* Close the service table (C syntax) */
  523. fprintf(SyscallTable,"\n};\n");
  524.  
  525. /*
  526. * We write some useful defines
  527. */
  528. fprintf(SyscallTable, "\n\n#define MIN_SYSCALL_NUMBER 0\n");
  529. fprintf(SyscallTable, "#define MAX_SYSCALL_NUMBER %d\n", SyscallId - 1);
  530. fprintf(SyscallTable, "#define NUMBER_OF_SYSCALLS %d\n", SyscallId);
  531. fprintf(SyscallTable, "ULONG %sNumberOfSysCalls = %d;\n", Name, SyscallId);
  532. }
  533.  
  534. /*++
  535. * WriteSpec
  536. *
  537. * Prints out the Spec Entry for a System Call.
  538. *
  539. * Params:
  540. * SpecFile - Spec File to which to write the header.
  541. *
  542. * SyscallName - Name of System Call for which to add the stub.
  543. *
  544. * CountArguments - Number of arguments to the System Call.
  545. *
  546. * Returns:
  547. * None.
  548. *
  549. * Remarks:
  550. * None.
  551. *
  552. *--*/
  553. void
  554. WriteSpec(FILE* StubFile,
  555. char* SyscallName,
  556. unsigned CountArguments)
  557. {
  558. unsigned i;
  559.  
  560. fprintf(StubFile, "@ stdcall %s", SyscallName);
  561.  
  562. fputc ('(', StubFile);
  563.  
  564. for (i = 0; i < CountArguments; ++ i)
  565. fputs ("ptr ", StubFile);
  566.  
  567. fputc (')', StubFile);
  568. fputc ('\n', StubFile);
  569. }
  570.  
  571. /*++
  572. * CreateSpec
  573. *
  574. * Parses a System Call Database and creates a spec file for all the entries.
  575. *
  576. * Params:
  577. * SyscallDb - System Call Database to parse.
  578. *
  579. * Files - Array of Spec Files to which to write.
  580. *
  581. * CountFiles - Number of Spec Files to create
  582. *
  583. * UseZw - Use Zw prefix?
  584. *
  585. * Returns:
  586. * None.
  587. *
  588. * Remarks:
  589. * None.
  590. *
  591. *--*/
  592. void
  593. CreateSpec(FILE * SyscallDb,
  594. FILE * Files[],
  595. unsigned CountFiles,
  596. unsigned UseZw)
  597. {
  598. char Line[INPUT_BUFFER_SIZE];
  599. char *NtSyscallName;
  600. char *SyscallArguments;
  601. unsigned CountArguments;
  602.  
  603. /* We loop until the end of the file */
  604. while ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL)) {
  605.  
  606. /* Extract the Name and Arguments */
  607. GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments);
  608. CountArguments = strtoul(SyscallArguments, NULL, 0);
  609.  
  610. /* Make sure we really extracted something */
  611. if (NtSyscallName) {
  612.  
  613. unsigned int i;
  614. for (i= 0; i < CountFiles; i++) {
  615.  
  616. if (!UseZw) {
  617. WriteSpec(Files[i],
  618. NtSyscallName,
  619. CountArguments);
  620. }
  621.  
  622. if (UseZw && NtSyscallName[0] == 'N' && NtSyscallName[1] == 't') {
  623.  
  624. NtSyscallName[0] = 'Z';
  625. NtSyscallName[1] = 'w';
  626. WriteSpec(Files[i],
  627. NtSyscallName,
  628. CountArguments);
  629. }
  630.  
  631. }
  632. }
  633. }
  634. }
  635.  
  636. void usage(char * argv0)
  637. {
  638. printf("Usage: %s [-arch <arch>] sysfuncs.lst w32ksvc.db napi.h ssdt.h napi.S zw.S win32k.S win32k.S\n"
  639. " sysfuncs.lst native system functions database\n"
  640. " w32ksvc.db native graphic functions database\n"
  641. " napi.h NTOSKRNL service table\n"
  642. " ssdt.h WIN32K service table\n"
  643. " napi.S NTDLL stubs\n"
  644. " zw.S NTOSKRNL Zw stubs\n"
  645. " win32k.S GDI32 stubs\n"
  646. " win32k.S USER32 stubs\n"
  647. " nt.pspec NTDLL exports\n"
  648. " -arch is optional, default is %s\n",
  649. argv0,
  650. ncitool_data[0].arch
  651. );
  652. }
  653.  
  654. int main(int argc, char* argv[])
  655. {
  656. FILE * Files[Arguments] = {0};
  657. int FileNumber, ArgOffset = 1;
  658. char * OpenType = "r";
  659.  
  660. /* Catch architecture argument */
  661. if (argc > 3 && !strcmp(argv[1],"-arch")) {
  662. for( arch_sel = 0; ncitool_data[arch_sel].arch; arch_sel++ )
  663. if (strcmp(argv[2],ncitool_data[arch_sel].arch) == 0)
  664. break;
  665. if (!ncitool_data[arch_sel].arch) {
  666. printf("Invalid arch '%s'\n", argv[2]);
  667. usage(argv[0]);
  668. return 1;
  669. }
  670. ArgOffset = 3;
  671. }
  672. /* Make sure all arguments all there */
  673. if (argc != Arguments + ArgOffset) {
  674. usage(argv[0]);
  675. return(1);
  676. }
  677.  
  678. /* Open all Output and bail out if any fail */
  679. for (FileNumber = 0; FileNumber < Arguments; FileNumber++) {
  680.  
  681. /* Open the File */
  682. if (FileNumber == 2) OpenType = "wb";
  683. Files[FileNumber] = fopen(argv[FileNumber + ArgOffset], OpenType);
  684.  
  685. /* Check for failure and error out if so */
  686. if (!Files[FileNumber]) {
  687. perror(argv[FileNumber + ArgOffset]);
  688. return (1);
  689. }
  690. }
  691.  
  692. /* Write the File Headers */
  693. WriteFileHeader(Files[NtosUserStubs],
  694. "System Call Stubs for Native API",
  695. argv[NtosUserStubs + ArgOffset]);
  696.  
  697. WriteFileHeader(Files[NtosKernelStubs],
  698. "System Call Stubs for Native API",
  699. argv[NtosKernelStubs + ArgOffset]);
  700. fputs("#include <ndk/asm.h>\n\n", Files[NtosKernelStubs]);
  701.  
  702. WriteFileHeader(Files[Win32kStubs],
  703. "System Call Stubs for Native API",
  704. argv[Win32kStubs + ArgOffset]);
  705.  
  706. /* Create the System Stubs */
  707. CreateStubs(Files[NativeSystemDb],
  708. &Files[NtosUserStubs],
  709. Files[NtosKernelStubs],
  710. MAIN_INDEX,
  711. 1,
  712. 1);
  713.  
  714. /* Create the Graphics Stubs */
  715. CreateStubs(Files[NativeGuiDb],
  716. &Files[Win32kStubs],
  717. NULL,
  718. WIN32K_INDEX,
  719. 1,
  720. 0);
  721.  
  722. /* Create the Service Tables */
  723. rewind(Files[NativeSystemDb]);
  724. CreateSystemServiceTable(Files[NativeSystemDb],
  725. Files[NtosServiceTable],
  726. "Main",
  727. argv[NtosServiceTable + ArgOffset]);
  728.  
  729. rewind(Files[NativeGuiDb]);
  730. CreateSystemServiceTable(Files[NativeGuiDb],
  731. Files[Win32kServiceTable],
  732. "Win32k",
  733. argv[Win32kServiceTable + ArgOffset]);
  734.  
  735. /* Create the Spec Files */
  736. rewind(Files[NativeSystemDb]);
  737. CreateSpec(Files[NativeSystemDb],
  738. &Files[NtSpec],
  739. 1,
  740. 0);
  741.  
  742. rewind(Files[NativeSystemDb]);
  743. CreateSpec(Files[NativeSystemDb],
  744. &Files[NtSpec],
  745. 1,
  746. 1);
  747.  
  748. /* Close all files */
  749. for (FileNumber = 0; FileNumber < Arguments-ArgOffset; FileNumber++) {
  750.  
  751. /* Close the File */
  752. fclose(Files[FileNumber]);
  753.  
  754. }
  755.  
  756. return(0);
  757. }
Add Comment
Please, Sign In to add comment