all: shell.bin
-OBJECTS = ../common/crt0.o shell.o
+OBJECTS= ../common/crt0.o shell.o
+LIBS= ../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a
-shell.bin: $(OBJECTS)
- $(LD) -Ttext 0x10000 $(OBJECTS) ../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a -o shell.exe
+shell.bin: $(OBJECTS) $(LIBS)
+ $(LD) -Ttext 0x10000 $(OBJECTS) $(LIBS) -o shell.exe
+ $(NM) --numeric-sort shell.exe > shell.sym
$(OBJCOPY) -O binary shell.exe shell.bin
include ../../rules.mak
-\r
-#include <internal/mmhal.h>\r
-\r
-#include <ddk/ntddk.h>\r
-#include <stdarg.h>\r
-#include <string.h>\r
-\r
-void debug_printf(char* fmt, ...)\r
-{\r
- va_list args;\r
- char buffer[255];\r
- \r
- va_start(args,fmt);\r
- vsprintf(buffer,fmt,args);\r
- OutputDebugStringA(buffer);\r
- va_end(args);\r
-}\r
-\r
-HANDLE KeyboardHandle;\r
-\r
-void ExecuteCd(char* cmdline)\r
-{\r
- UCHAR Buffer[255];\r
- \r
- debug_printf("ExecuteCd(cmdline %s)\n",cmdline);\r
- \r
- if (cmdline[0] != '\\' &&\r
- cmdline[1] != ':')\r
- {\r
- GetCurrentDirectoryA(255,Buffer);\r
- }\r
- else\r
- {\r
- Buffer[0] = 0;\r
- }\r
- debug_printf("Buffer %s\n",Buffer);\r
- \r
- lstrcatA(Buffer,cmdline);\r
- \r
- debug_printf("Buffer %s\n",Buffer);\r
- \r
- if (Buffer[lstrlenA(Buffer)-1] != '\\')\r
- {\r
- lstrcatA(Buffer,"\\");\r
- }\r
- debug_printf("Buffer %s\n",Buffer);\r
- \r
- SetCurrentDirectoryA(Buffer);\r
-}\r
-\r
-void ExecuteDir(char* cmdline)\r
-{\r
- HANDLE shandle;\r
- WIN32_FIND_DATA FindData;\r
-\r
- shandle = FindFirstFile("*",&FindData);\r
-\r
- if (shandle==INVALID_HANDLE_VALUE)\r
- {\r
- return;\r
- }\r
- do\r
- {\r
- debug_printf("Scanning %s\n",FindData.cFileName);\r
- } while(FindNextFile(shandle,&FindData));\r
-}\r
-\r
-void ExecuteType(char* cmdline)\r
-{\r
- HANDLE FileHandle;\r
- char c;\r
- DWORD Result;\r
- \r
- FileHandle = CreateFile(cmdline,\r
- FILE_GENERIC_READ,\r
- 0,\r
- NULL,\r
- OPEN_EXISTING,\r
- 0,\r
- NULL);\r
- while (ReadFile(FileHandle,\r
- &c,\r
- 1,\r
- &Result,\r
- NULL))\r
- {\r
- debug_printf("%c",c);\r
- c = 0;\r
- }\r
-}\r
-\r
-int ExecuteProcess(char* name, char* cmdline)\r
-{\r
- PROCESS_INFORMATION ProcessInformation;\r
- STARTUPINFO StartupInfo;\r
- char arguments;\r
- BOOL ret;\r
- \r
- memset(&StartupInfo,0,sizeof(StartupInfo));\r
- StartupInfo.cb = sizeof(STARTUPINFO);\r
- StartupInfo.lpTitle = name;\r
- \r
- ret = CreateProcessA(name,\r
- cmdline,\r
- NULL,\r
- NULL,\r
- TRUE,\r
- CREATE_NEW_CONSOLE,\r
- NULL,\r
- NULL,\r
- &StartupInfo,\r
- &ProcessInformation);\r
- if (ret)\r
- {\r
- WaitForSingleObject(ProcessInformation.hProcess,INFINITE);\r
- }\r
- return(ret);\r
-}\r
-\r
-void ExecuteCommand(char* line)\r
-{\r
- char* cmd;\r
- char* tail;\r
- \r
- if (line[1] == ':' && line[2] == 0)\r
- {\r
- line[2] = '\\';\r
- line[3] = 0;\r
- SetCurrentDirectoryA(line);\r
- return;\r
- }\r
- \r
- tail = line;\r
- while ((*tail)!=' ' && (*tail)!=0)\r
- {\r
- tail++; \r
- }\r
- if ((*tail)==' ')\r
- {\r
- *tail = 0;\r
- tail++;\r
- }\r
- cmd = line;\r
- \r
-// debug_printf("cmd '%s' tail '%s'\n",cmd,tail);\r
- \r
- if (cmd==NULL)\r
- {\r
- return;\r
- }\r
- if (strcmp(cmd,"cd")==0)\r
- {\r
- ExecuteCd(tail);\r
- return;\r
- }\r
- if (strcmp(cmd,"dir")==0)\r
- {\r
- ExecuteDir(tail);\r
- return;\r
- }\r
- if (strcmp(cmd,"type")==0)\r
- {\r
- ExecuteType(tail); \r
- return;\r
- }\r
- if (ExecuteProcess(cmd,tail))\r
- {\r
- debug_printf("Done ExecuteProcess\n");\r
- return;\r
- }\r
- debug_printf("Unknown command\n");\r
-}\r
-\r
-void ReadLine(char* line)\r
-{\r
- KEY_EVENT_RECORD KeyEvent;\r
- DWORD Result;\r
- UCHAR CurrentDir[255];\r
- \r
- GetCurrentDirectoryA(255,CurrentDir);\r
- debug_printf(CurrentDir);\r
- \r
- do\r
- {\r
- ReadFile(KeyboardHandle,\r
- &KeyEvent,\r
- sizeof(KEY_EVENT_RECORD),\r
- &Result,\r
- NULL);\r
- if (KeyEvent.bKeyDown && KeyEvent.AsciiChar != 0)\r
- {\r
- debug_printf("%c",KeyEvent.AsciiChar);\r
- *line = KeyEvent.AsciiChar;\r
- line++;\r
- }\r
- } while (!(KeyEvent.bKeyDown && KeyEvent.AsciiChar == '\n'));\r
- ReadFile(KeyboardHandle,\r
- &KeyEvent,\r
- sizeof(KEY_EVENT_RECORD),\r
- &Result,\r
- NULL);\r
- line--;\r
- *line = 0;\r
-}\r
-\r
-void main()\r
-{\r
- static char line[255];\r
- \r
- KERNEL32_Init();\r
- \r
- NtDisplayString("Shell Starting...\n");\r
- \r
- KeyboardHandle = CreateFile("Keyboard",\r
- FILE_GENERIC_READ,\r
- 0,\r
- NULL,\r
- OPEN_EXISTING,\r
- 0,\r
- NULL);\r
- \r
- SetCurrentDirectoryA("C:\\");\r
- \r
- for(;;)\r
- {\r
- ReadLine(line);\r
- ExecuteCommand(line);\r
- }\r
-}\r
+#include <internal/mmhal.h>
+
+#include <ddk/ntddk.h>
+#include <stdarg.h>
+#include <string.h>
+
+HANDLE InputHandle, OutputHandle;
+
+void debug_printf(char* fmt, ...)
+{
+ va_list args;
+ char buffer[255];
+
+ va_start(args,fmt);
+ vsprintf(buffer,fmt,args);
+ WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
+ va_end(args);
+}
+
+void ExecuteCd(char* cmdline)
+{
+ UCHAR Buffer[255];
+
+ debug_printf("ExecuteCd(cmdline %s)\n",cmdline);
+
+ if (cmdline[0] != '\\' &&
+ cmdline[1] != ':')
+ {
+ GetCurrentDirectoryA(255,Buffer);
+ }
+ else
+ {
+ Buffer[0] = 0;
+ }
+ debug_printf("Buffer %s\n",Buffer);
+
+ lstrcatA(Buffer,cmdline);
+
+ debug_printf("Buffer %s\n",Buffer);
+
+ if (Buffer[lstrlenA(Buffer)-1] != '\\')
+ {
+ lstrcatA(Buffer,"\\");
+ }
+ debug_printf("Buffer %s\n",Buffer);
+
+ SetCurrentDirectoryA(Buffer);
+}
+
+void ExecuteDir(char* cmdline)
+{
+ HANDLE shandle;
+ WIN32_FIND_DATA FindData;
+
+ shandle = FindFirstFile("*",&FindData);
+
+ if (shandle==INVALID_HANDLE_VALUE)
+ {
+ return;
+ }
+ do
+ {
+ debug_printf("Scanning %s\n",FindData.cFileName);
+ } while(FindNextFile(shandle,&FindData));
+}
+
+void ExecuteType(char* cmdline)
+{
+ HANDLE FileHandle;
+ char c;
+ DWORD Result;
+
+ FileHandle = CreateFile(cmdline,
+ FILE_GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ while (ReadFile(FileHandle,
+ &c,
+ 1,
+ &Result,
+ NULL))
+ {
+ debug_printf("%c",c);
+ c = 0;
+ }
+}
+
+int ExecuteProcess(char* name, char* cmdline)
+{
+ PROCESS_INFORMATION ProcessInformation;
+ STARTUPINFO StartupInfo;
+ char arguments;
+ BOOL ret;
+
+ memset(&StartupInfo,0,sizeof(StartupInfo));
+ StartupInfo.cb = sizeof(STARTUPINFO);
+ StartupInfo.lpTitle = name;
+
+ ret = CreateProcessA(name,
+ cmdline,
+ NULL,
+ NULL,
+ TRUE,
+ CREATE_NEW_CONSOLE,
+ NULL,
+ NULL,
+ &StartupInfo,
+ &ProcessInformation);
+ if (ret)
+ {
+ WaitForSingleObject(ProcessInformation.hProcess,INFINITE);
+ }
+ return(ret);
+}
+
+void ExecuteCommand(char* line)
+{
+ char* cmd;
+ char* tail;
+
+ if (line[1] == ':' && line[2] == 0)
+ {
+ line[2] = '\\';
+ line[3] = 0;
+ SetCurrentDirectoryA(line);
+ return;
+ }
+
+ tail = line;
+ while ((*tail)!=' ' && (*tail)!=0)
+ {
+ tail++;
+ }
+ if ((*tail)==' ')
+ {
+ *tail = 0;
+ tail++;
+ }
+ cmd = line;
+
+// debug_printf("cmd '%s' tail '%s'\n",cmd,tail);
+
+ if (cmd==NULL)
+ {
+ return;
+ }
+ if (strcmp(cmd,"cd")==0)
+ {
+ ExecuteCd(tail);
+ return;
+ }
+ if (strcmp(cmd,"dir")==0)
+ {
+ ExecuteDir(tail);
+ return;
+ }
+ if (strcmp(cmd,"type")==0)
+ {
+ ExecuteType(tail);
+ return;
+ }
+ if (ExecuteProcess(cmd,tail))
+ {
+ debug_printf("Done ExecuteProcess\n");
+ return;
+ }
+ debug_printf("Unknown command\n");
+}
+
+void ReadLine(char* line)
+{
+ KEY_EVENT_RECORD KeyEvent;
+ DWORD Result;
+ UCHAR CurrentDir[255];
+
+ GetCurrentDirectoryA(255,CurrentDir);
+ debug_printf(CurrentDir);
+
+ do
+ {
+ ReadConsoleA(InputHandle,
+ &KeyEvent,
+ sizeof(KEY_EVENT_RECORD),
+ &Result,
+ NULL);
+ if (KeyEvent.bKeyDown && KeyEvent.AsciiChar != 0)
+ {
+ debug_printf("%c", KeyEvent.AsciiChar);
+ *line = KeyEvent.AsciiChar;
+ line++;
+ }
+ } while (!(KeyEvent.bKeyDown && KeyEvent.AsciiChar == '\n'));
+ ReadFile(InputHandle,
+ &KeyEvent,
+ sizeof(KEY_EVENT_RECORD),
+ &Result,
+ NULL);
+ line--;
+ *line = 0;
+}
+
+void main()
+{
+ static char line[255];
+
+ KERNEL32_Init();
+
+ AllocConsole();
+ InputHandle = GetStdHandle(STD_INPUT_HANDLE);
+ OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ debug_printf("Shell Starting...\n");
+
+ SetCurrentDirectoryA("C:\\");
+
+ for(;;)
+ {
+ ReadLine(line);
+ ExecuteCommand(line);
+ }
+}
+
--- /dev/null
+@ECHO OFF
+
+:
+: copy files to HD...
+:
+COPY /Y SHELL.BIN C:\reactos\system\SHELL.bin
+COPY /Y BLUES.o C:\reactos\system\drivers\BLUES.o
+COPY /Y KEYBOARD.o C:\reactos\system\drivers\KEYBOARD.o
+
+:
+: present a menu to the booter...
+:
+ECHO 1) Keyboard,IDE,VFatFSD
+ECHO 2) IDE,VFatFSD
+ECHO 3) No Drivers
+CHOICE /C:123 /T:2,10 "Select kernel boot config"
+IF ERRORLEVEL 3 GOTO :L3
+IF ERRORLEVEL 2 GOTO :L2
+
+:L1
+CLS
+LOADROS KIMAGE.BIN KEYBOARD.O IDE.O VFATFSD.O
+GOTO :END
+
+:L2
+CLS
+LOADROS KIMAGE.BIN IDE.O VFATFSD.O
+GOTO :END
+
+:L3
+CLS
+LOADROS KIMAGE.BIN
+GOTO :END
+
+:END
+EXIT
+
+
--- /dev/null
+
+#undef WIN32_LEAN_AND_MEAN
+#include <internal/mmhal.h>
+#include <internal/halio.h>
+#include <ddk/ntddk.h>
+#include <internal/string.h>
+#include <defines.h>
+
+//#define NDEBUG
+#include <internal/debug.h>
+
+
+
+#define FSCTL_GET_CONSOLE_SCREEN_BUFFER_INFO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 254, DO_DIRECT_IO, FILE_READ_ACCESS|FILE_WRITE_ACCESS)
+#define FSCTL_SET_CONSOLE_SCREEN_BUFFER_INFO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 255, DO_DIRECT_IO, FILE_READ_ACCESS|FILE_WRITE_ACCESS)
+
+
+
+CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
+
+
+VOID ScrStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
+
+}
+
+NTSTATUS ScrDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
+ ULONG ControlCode;
+ NTSTATUS Status;
+ char *UserBuf = Irp->UserBuffer;
+ int i;
+
+ switch (stk->MajorFunction)
+ {
+ case IRP_MJ_CREATE:
+ case IRP_MJ_CLOSE:
+ Status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MJ_WRITE:
+ for(i=0;i<stk->Parameters.Write.Length;i++)
+ __putchar(UserBuf[i]);
+ Status = STATUS_SUCCESS;
+ break;
+ case IRP_MJ_DEVICE_CONTROL:
+ ControlCode = stk->Parameters.DeviceIoControl.IoControlCode;
+ if ( ControlCode == FSCTL_GET_CONSOLE_SCREEN_BUFFER_INFO ) {
+ // printk("get console screen buffer info\n");
+ ConsoleScreenBufferInfo.dwCursorPosition.X=__wherex();
+ ConsoleScreenBufferInfo.dwCursorPosition.Y=__wherey();
+
+ __getscreensize(&ConsoleScreenBufferInfo.dwSize.X, &ConsoleScreenBufferInfo.dwSize.Y );
+
+ memcpy(UserBuf,&ConsoleScreenBufferInfo,sizeof(CONSOLE_SCREEN_BUFFER_INFO));
+ Status = STATUS_SUCCESS;
+ }
+ else if ( ControlCode == FSCTL_SET_CONSOLE_SCREEN_BUFFER_INFO ) {
+ // printk("set console screen buffer info\n");
+ memcpy(&ConsoleScreenBufferInfo,UserBuf,sizeof(CONSOLE_SCREEN_BUFFER_INFO));
+ __goxy(ConsoleScreenBufferInfo.dwCursorPosition.X,ConsoleScreenBufferInfo.dwCursorPosition.Y);
+ Status = STATUS_SUCCESS;
+
+ }
+ break;
+
+ default:
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+
+
+// DPRINT("Status %d\n",Status);
+ return(Status);
+}
+
+/*
+ * Module entry point
+ */
+NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
+{
+ PDEVICE_OBJECT DeviceObject;
+ ANSI_STRING adevice_name;
+ UNICODE_STRING device_name;
+ ANSI_STRING asymlink_name;
+ UNICODE_STRING symlink_name;
+
+ DbgPrint("Screen Driver 0.0.4\n");
+
+
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrDispatch;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrDispatch;
+ DriverObject->MajorFunction[IRP_MJ_READ] = ScrDispatch;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = ScrDispatch;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL ] = ScrDispatch;
+ DriverObject->DriverStartIo = ScrStartIo;
+
+ //ScrSwitchToBlueScreen();
+
+
+ RtlInitAnsiString(&adevice_name,"\\Device\\BlueScreen");
+ RtlAnsiStringToUnicodeString(&device_name,&adevice_name,TRUE);
+ IoCreateDevice(DriverObject,0,&device_name,FILE_DEVICE_SCREEN,0,
+ TRUE,&DeviceObject);
+
+
+ RtlInitAnsiString(&asymlink_name,"\\??\\BlueScreen");
+ RtlAnsiStringToUnicodeString(&symlink_name,&asymlink_name,TRUE);
+ IoCreateSymbolicLink(&symlink_name,&device_name);
+
+ return(STATUS_SUCCESS);
+}
+
+
+
+
+/* FUNCTIONS ***************************************************************/
+
+
+void ScrSwitchToBlueScreen(void)
+/*
+ * FUNCTION: Switches the monitor to text mode and writes a blue background
+ * NOTE: This function is entirely self contained and can be used from any
+ * graphics mode.
+ */
+{
+
+ /*
+ * Reset the cursor position
+ */
+ ConsoleScreenBufferInfo.dwCursorPosition.X=__wherex();
+ ConsoleScreenBufferInfo.dwCursorPosition.Y=__wherey();
+
+ __getscreensize(&ConsoleScreenBufferInfo.dwSize.X, &ConsoleScreenBufferInfo.dwSize.Y );
+
+
+ /*
+ * This code section is taken from the sample routines by
+ * Jeff Morgan (kinfira@hotmail.com)
+ */
+
+}
+
+
+
+
+
+
+
+
+
+
IN DWORD Offset,
IN DWORD Size)
{
- WORD UnicodeBuffer[IDE_MAX_NAME_LENGTH];
+ WCHAR UnicodeBuffer[IDE_MAX_NAME_LENGTH];
NTSTATUS RC;
ANSI_STRING AnsiName, AnsiSymLink;
UNICODE_STRING UnicodeName, SymLink;
// Create a unicode device name
RtlInitAnsiString(&AnsiName, DeviceName);
- UnicodeName.MaximumLength = IDE_MAX_NAME_LENGTH;
+ UnicodeName.MaximumLength = IDE_MAX_NAME_LENGTH * sizeof(WCHAR);
UnicodeName.Buffer = UnicodeBuffer;
RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, FALSE);
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#ifndef __dj_include_conio_h_
+#define __dj_include_conio_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _POSIX_SOURCE
+
+
+extern int directvideo; /* ignored by gppconio */
+extern int _wscroll;
+
+#define _NOCURSOR 0
+#define _SOLIDCURSOR 1
+#define _NORMALCURSOR 2
+
+struct text_info {
+ unsigned char winleft;
+ unsigned char wintop;
+ unsigned char winright;
+ unsigned char winbottom;
+ unsigned char attribute;
+ unsigned char normattr;
+ unsigned char currmode;
+ unsigned char screenheight;
+ unsigned char screenwidth;
+ unsigned char curx;
+ unsigned char cury;
+};
+
+enum text_modes { LASTMODE=-1, BW40=0, C40, BW80, C80, MONO=7, C4350=64 };
+
+enum COLORS {
+ /* dark colors */
+ BLACK,
+ BLUE,
+ GREEN,
+ CYAN,
+ RED,
+ MAGENTA,
+ BROWN,
+ LIGHTGRAY,
+ /* light colors */
+ DARKGRAY,
+ LIGHTBLUE,
+ LIGHTGREEN,
+ LIGHTCYAN,
+ LIGHTRED,
+ LIGHTMAGENTA,
+ YELLOW,
+ WHITE
+};
+
+#define BLINK 0x80 /* blink bit */
+
+void blinkvideo(void);
+char * cgets(char *_str);
+void clreol(void);
+void clrscr(void);
+int _conio_kbhit(void); /* checks for ungetch char */
+//int cprintf(const char *_format, ...) __attribute__((format(printf,1,2)));
+int cputs(const char *_str);
+//int cscanf(const char *_format, ...) __attribute__((format(scanf,1,2)));
+void delline(void);
+int getch(void);
+int getche(void);
+int gettext(int _left, int _top, int _right, int _bottom, void *_destin);
+void gettextinfo(struct text_info *_r);
+void gotoxy(int _x, int _y);
+void gppconio_init(void);
+void highvideo(void);
+void insline(void);
+void intensevideo(void);
+void lowvideo(void);
+int movetext(int _left, int _top, int _right, int _bottom, int _destleft, int _desttop);
+void normvideo(void);
+int putch(int _c);
+int puttext(int _left, int _top, int _right, int _bottom, void *_source);
+void _setcursortype(int _type);
+void _set_screen_lines(int _nlines);
+void textattr(int _attr);
+void textbackground(int _color);
+void textcolor(int _color);
+void textmode(int _mode);
+int ungetch(int);
+unsigned int wherex(void);
+unsigned int wherey(void);
+void window(int _left, int _top, int _right, int _bottom);
+
+#define kbhit _conio_kbhit /* Who ever includes gppconio.h probably
+ also wants _conio_kbhit and not kbhit
+ from libc */
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifndef __dj_ENFORCE_FUNCTION_CALLS
+#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__dj_include_conio_h_ */
--- /dev/null
+#ifndef __include_direct_h_
+#define __include_direct_h_
+
+struct _diskfree_t {
+ unsigned short total_clusters;
+ unsigned short avail_clusters;
+ unsigned short sectors_per_cluster;
+ unsigned short bytes_per_sector;
+};
+
+
+int _chdrive( int drive );
+int _getdrive( void );
+char *_getcwd( char *buffer, int maxlen );
+
+int _chdir(const char *_path);
+char *_getcwd(char *, int);
+int _mkdir(const char *_path);
+int _rmdir(const char *_path);
+unsigned int _getdiskfree(unsigned int _drive, struct _diskfree_t *_diskspace);
+#define chdir _chdir
+#define getcwd _getcwd
+#define mkdir _mkdir
+#define rmdir _rmdir
+
+
+#endif
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#ifndef __dj_include_fcntl_h_
+#define __dj_include_fcntl_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _IOREAD 000010
+#define _IOWRT 000020
+#define _IOMYBUF 000040
+#define _IOEOF 000100
+#define _IOERR 000200
+#define _IOSTRG 000400
+#define _IORW 001000
+#define _IOAPPEND 002000
+#define _IORMONCL 004000 /* remove on close, for temp files */
+/* if _flag & _IORMONCL, ._name_to_remove needs freeing */
+#define _IOUNGETC 010000 /* there is an ungetc'ed character in the buffer */
+
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+#ifndef __STRICT_ANSI__
+
+#define FD_CLOEXEC 0x0001
+
+#define F_DUPFD 1
+#define F_GETFD 2
+#define F_GETFL 3
+#define F_GETLK 4
+#define F_SETFD 5
+#define F_SETFL 6
+#define F_SETLK 7
+#define F_SETLKW 8
+
+#define F_UNLCK 0
+#define F_RDLCK 1
+#define F_WRLCK 2
+
+#define O_RDONLY 0x0000
+#define O_WRONLY 0x0001
+#define O_RDWR 0x0002
+#define O_ACCMODE 0x0003
+
+#define O_BINARY 0x0004 /* must fit in char, reserved by dos */
+#define O_TEXT 0x0008 /* must fit in char, reserved by dos */
+
+#define O_RANDOM 0x0010
+#define O_SEQUENTIAL 0x0020
+
+
+#define O_TEMPORARY 0x0040
+
+/* temporary access hint */
+
+
+
+/* sequential/random access hints */
+
+
+
+
+#define O_NOINHERIT 0x0080 /* DOS-specific */
+
+#define O_CREAT 0x0100 /* second byte, away from DOS bits */
+#define O_EXCL 0x0200
+#define O_NOCTTY 0x0400
+#define O_TRUNC 0x0800
+#define O_APPEND 0x1000
+#define O_NONBLOCK 0x2000
+
+#define O_SHORT_LIVED 0x1000
+
+//#include <sys/types.h>
+#include <sys/stat.h>
+
+//typedef int dev_t;
+//typedef int ino_t;
+//typedef int mode_t;
+//typedef int nlink_t;
+
+#include <io.h>
+
+
+struct flock {
+ off_t l_len;
+ pid_t l_pid;
+ off_t l_start;
+ short l_type;
+ short l_whence;
+};
+
+extern int _fmode; /* O_TEXT or O_BINARY */
+
+//int open(const char *_path, int _oflag, ...);
+//int creat(const char *_path, int _mode);
+int fcntl(int _fildes, int _cmd, ...);
+
+#ifndef _POSIX_SOURCE
+
+
+#define S_IREAD S_IRUSR
+#define S_IWRITE S_IWUSR
+#define S_IEXEC S_IXUSR
+
+/*
+ * For compatibility with other DOS C compilers.
+ */
+
+#define _O_RDONLY O_RDONLY
+#define _O_WRONLY O_WRONLY
+#define _O_RDWR O_RDWR
+#define _O_APPEND O_APPEND
+#define _O_CREAT O_CREAT
+#define _O_TRUNC O_TRUNC
+#define _O_EXCL O_EXCL
+#define _O_TEXT O_TEXT
+#define _O_BINARY O_BINARY
+#define _O_NOINHERIT O_NOINHERIT
+#define _O_RANDOM O_RANDOM
+#define _O_SEQUENTIAL O_RANDOM
+#define _O_SHORT_LIVED O_SHORT_LIVED
+#define _O_TEMPORARY O_TEMPORARY
+
+#define _S_IREAD S_IRUSR
+#define _S_IWRITE S_IWUSR
+#define _S_IEXEC S_IXUSR
+
+/*
+ * Support for advanced filesystems (Windows 9x VFAT, NTFS, LFN etc.)
+ */
+
+#define _FILESYS_UNKNOWN 0x80000000U
+#define _FILESYS_CASE_SENSITIVE 0x0001
+#define _FILESYS_CASE_PRESERVED 0x0002
+#define _FILESYS_UNICODE 0x0004
+#define _FILESYS_LFN_SUPPORTED 0x4000
+#define _FILESYS_VOL_COMPRESSED 0x8000
+
+unsigned _get_volume_info (const char *_path, int *_max_file_len, int *_max_path_len, char *_filesystype);
+char _use_lfn (const char *_path);
+char *_lfn_gen_short_fname (const char *_long_fname, char *_short_fname);
+
+#define _LFN_CTIME 1
+#define _LFN_ATIME 2
+
+unsigned _lfn_get_ftime (int _handle, int _which);
+
+char _preserve_fncase (void);
+#define _USE_LFN _use_lfn(0) /* assume it's the same on ALL drives */
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifndef __dj_ENFORCE_FUNCTION_CALLS
+#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__dj_include_fcntl_h_ */
/*
* printf style functions
*/
+void __putchar(char c);
+void __goxy(unsigned x, unsigned y);
+unsigned __wherex (void);
+unsigned __wherey (void);
+void __getscreensize (unsigned *maxx, unsigned *maxy);
asmlinkage void printk(const char* fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args);
int sprintf(char* buf, const char* fmt, ...);
VOID KeInit(VOID);
VOID HalInitConsole(boot_param* bp);
+/*
+ * Loader functions (called in main())
+ */
+VOID LdrInitModuleManagement(VOID);
+VOID LdrLoadAutoConfigDrivers(VOID);
+
#endif
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#ifndef __dj_include_io_h_
+#define __dj_include_io_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _POSIX_SOURCE
+
+#include <sys/types.h>
+#include <internal/types.h>
+
+
+/*
+ * For compatibility with other DOS C compilers.
+ */
+
+#define _A_NORMAL 0x00 /* Normal file - No read/write restrictions */
+#define _A_RDONLY 0x01 /* Read only file */
+#define _A_HIDDEN 0x02 /* Hidden file */
+#define _A_SYSTEM 0x04 /* System file */
+#define _A_VOLID 0x08 /* Volume ID file */
+#define _A_SUBDIR 0x10 /* Subdirectory */
+#define _A_ARCH 0x20 /* Archive file */
+
+
+struct _finddata_t {
+ char reserved[21] __attribute__((packed));
+ unsigned char attrib __attribute__((packed));
+ unsigned short time_create __attribute__((packed));
+ unsigned short time_access __attribute__((packed));
+ unsigned short time_write __attribute__((packed));
+ unsigned long size __attribute__((packed));
+ char name[256] __attribute__((packed));
+};
+
+int chsize(int handle, long size);
+int close(int _fd);
+int _close(int _fd);
+int _creat(const char *_path, int _attrib);
+unsigned int _commit(int _handle);
+ssize_t crlf2nl(char *_buffer, ssize_t _length);
+int _dos_lock(int _fd, long _offset, long _length);
+long filelength(int _handle);
+long _findfirst(char *_name, struct _finddata_t *_result);
+int _findnext(long handle, struct _finddata_t *_result);
+int _findclose(long handle);
+short _get_dev_info(int _arg);
+int lock(int _fd, long _offset, long _length);
+int _open(const char *_path, int _oflag, ...);
+size_t _read(int _fd, void *_buf,size_t _nbyte);
+int setmode(int _fd, int _newmode);
+int _setmode(int _fd, int _newmode);
+off_t tell(int _fd);
+int _dos_unlock(int _fd, long _offset, long _length);
+int unlock(int _fd, long _offset, long _length);
+size_t _write(int _fd, const void *_buf, size_t _nbyte);
+int _chmod(const char *_path, int _func, ...);
+void _flush_disk_cache(void);
+
+int _dup( int handle);
+int _dup2( int handle1, int handle2 );
+long _lseek(int _filedes, long _offset, int _whence);
+int _open_osfhandle ( void *osfhandle, int flags );
+
+#define open _open
+#define dup _dup
+#define dup2 _dup2
+#define lseek _lseek
+#define open_osfhandle _open_osfhandle
+
+
+
+
+#define sopen(path, access, shflag, mode) \
+ open((path), (access)|(shflag), (mode))
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifndef __dj_ENFORCE_FUNCTION_CALLS
+#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__dj_include_io_h_ */
#include <ntdll/pagesize.h>
/* definitions */
-#define HEAP_ADMIN_SIZE 8
-#define HEAP_FRAG_ADMIN_SIZE 8
+#define HEAP_ADMIN_SIZE (sizeof(HEAP_BLOCK))
+#define HEAP_FRAG_ADMIN_SIZE (sizeof(HEAP_FRAGMENT))
#define HEAP_ROUNDVAL (2*(HEAP_ADMIN_SIZE)-1)
#define HEAP_FRAGMENT_THRESHOLD 256
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#ifndef __dj_include_process_h_
+#define __dj_include_process_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _POSIX_SOURCE
+
+int _dos_exec(const char *program, const char *args, char *const _envp[]);
+
+int execl(const char *_path, const char *_argv0, ...);
+int execle(const char *_path, const char *_argv0, ... /*, char *const _envp[] */);
+int execlp(const char *_path, const char *_argv0, ...);
+int execlpe(const char *_path, const char *_argv0, ... /*, char *const _envp[] */);
+
+int execv(const char *_path,const char *const _argv[]);
+int execve(const char *_path,const char *const _argv[],const char *const _envp[]);
+int execvp(const char *_path,const char *const _argv[]);
+int execvpe(const char *_path,const char *const _argv[],const char *const _envp[]);
+
+int spawnl(int _mode, const char *_path, const char *_argv0, ...);
+int spawnle(int _mode, const char *_path, const char *_argv0, ... /*, char *const _envp[] */);
+int spawnlp(int _mode, const char *_path, const char *_argv0, ...);
+int spawnlpe(int _mode, const char *_path, const char *_argv0, ... /*, char *const _envp[] */);
+
+int spawnv(int _mode, const char *_path,const char *const _argv[]);
+int spawnve(int _mode, const char *_path,const char *const _argv[],const char *const _envp[]);
+int spawnvp(int _mode, const char *_path,const char *const _argv[]);
+int spawnvpe(int _mode, const char *_path,const char *const _argv[],const char *const _envp[]);
+
+#define P_WAIT 1
+#define P_NOWAIT 2 /* always generates error */
+#define P_OVERLAY 3
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifndef __dj_ENFORCE_FUNCTION_CALLS
+#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__dj_include_process_h_ */
--- /dev/null
+#ifndef _include_share_h_
+#define _include_share_h_
+
+
+#define SH_COMPAT 0x0000
+#define SH_DENYRW 0x0010
+#define SH_DENYWR 0x0020
+#define SH_DENYRD 0x0030
+#define SH_DENYNO 0x0040
+
+#define _SH_COMPAT SH_COMPAT
+#define _SH_DENYRW SH_DENYRW
+#define _SH_DENYWR SH_DENYWR
+#define _SH_DENYRD SH_DENYRD
+#define _SH_DENYNO SH_DENYNO
+
+#endif
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+#ifndef __dj_include_stdio_h_
+#define __dj_include_stdio_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+#include <sys/djtypes.h>
+
+#define _IOFBF 00001
+#define _IONBF 00002
+#define _IOLBF 00004
+
+#define BUFSIZ 16384
+#define EOF (-1)
+#define FILENAME_MAX 260
+#define FOPEN_MAX 20
+#define L_tmpnam 260
+#ifndef NULL
+#define NULL 0
+#endif
+#define TMP_MAX 999999
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#define _IOREAD 000010
+#define _IOWRT 000020
+#define _IOMYBUF 000040
+#define _IOEOF 000100
+#define _IOERR 000200
+#define _IOSTRG 000400
+#define _IORW 001000
+#define _IOAPPEND 002000
+#define _IORMONCL 004000 /* remove on close, for temp files */
+/* if _flag & _IORMONCL, ._name_to_remove needs freeing */
+#define _IOUNGETC 010000 /* there is an ungetc'ed character in the buffer */
+
+
+#include <internal/types.h>
+
+__DJ_va_list
+#undef __DJ_va_list
+#define __DJ_va_list
+
+#ifndef _FILE_DEFINED
+typedef struct {
+ char *_ptr;
+ int _cnt;
+ char *_base;
+ int _flag;
+ int _file;
+ int _ungotchar;
+ int _bufsiz;
+ char *_name_to_remove;
+} FILE;
+#define _FILE_DEFINED
+#endif
+
+typedef unsigned long fpos_t;
+
+extern FILE _iob[];
+
+#define stdin (&_iob[0])
+#define stdout (&_iob[1])
+#define stderr (&_iob[2])
+#define stdaux (&_iob[3])
+#define stdprn (&_iob[4])
+
+void clearerr(FILE *_stream);
+int fclose(FILE *_stream);
+int feof(FILE *_stream);
+int ferror(FILE *_stream);
+int fflush(FILE *_stream);
+int fgetc(FILE *_stream);
+int fgetpos(FILE *_stream, fpos_t *_pos);
+char * fgets(char *_s, int _n, FILE *_stream);
+FILE * fopen(const char *_filename, const char *_mode);
+int fprintf(FILE *_stream, const char *_format, ...);
+int fputc(int _c, FILE *_stream);
+int fputs(const char *_s, FILE *_stream);
+size_t fread(void *_ptr, size_t _size, size_t _nelem, FILE *_stream);
+FILE * freopen(const char *_filename, const char *_mode, FILE *_stream);
+int fscanf(FILE *_stream, const char *_format, ...);
+int fseek(FILE *_stream, long _offset, int _mode);
+int fsetpos(FILE *_stream, const fpos_t *_pos);
+long ftell(FILE *_stream);
+size_t fwrite(const void *_ptr, size_t _size, size_t _nelem, FILE *_stream);
+int getc(FILE *_stream);
+int getchar(void);
+char * gets(char *_s);
+void perror(const char *_s);
+int printf(const char *_format, ...);
+int putc(int _c, FILE *_stream);
+int putchar(int _c);
+int puts(const char *_s);
+int remove(const char *_filename);
+int rename(const char *_old, const char *_new);
+void rewind(FILE *_stream);
+int scanf(const char *_format, ...);
+void setbuf(FILE *_stream, char *_buf);
+int setvbuf(FILE *_stream, char *_buf, int _mode, size_t _size);
+int sprintf(char *_s, const char *_format, ...);
+int sscanf(const char *_s, const char *_format, ...);
+FILE * tmpfile(void);
+char * tmpnam(char *_s);
+char * _tmpnam(char *_s);
+int ungetc(int _c, FILE *_stream);
+int vfprintf(FILE *_stream, const char *_format, va_list _ap);
+int vprintf(const char *_format, va_list _ap);
+int vsprintf(char *_s, const char *_format, va_list _ap);
+
+#ifndef __STRICT_ANSI__
+
+#define L_ctermid
+#define L_cusrid
+/* #define STREAM_MAX 20 - DOS can change this */
+
+int fileno(FILE *_stream);
+int _fileno(FILE *_stream);
+FILE * fdopen(int _fildes, const char *_type);
+int pclose(FILE *_pf);
+FILE * popen(const char *_command, const char *_mode);
+
+#ifndef _POSIX_SOURCE
+
+void _djstat_describe_lossage(FILE *_to_where);
+int _doprnt(const char *_fmt, va_list _args, FILE *_f);
+int _doscan(FILE *_f, const char *_fmt, void **_argp);
+int _doscan_low(FILE *, int (*)(FILE *_get), int (*_unget)(int, FILE *), const char *_fmt, void **_argp);
+int fpurge(FILE *_f);
+int getw(FILE *_f);
+int mkstemp(char *_template);
+char * mktemp(char *_template);
+int putw(int _v, FILE *_f);
+void setbuffer(FILE *_f, void *_buf, int _size);
+void setlinebuf(FILE *_f);
+char * tempnam(const char *_dir, const char *_prefix);
+int _rename(const char *_old, const char *_new); /* Simple (no directory) */
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifndef __dj_ENFORCE_FUNCTION_CALLS
+#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__dj_include_stdio_h_ */
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#ifndef __dj_include_stdlib_h_
+#define __dj_include_stdlib_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+//#include <sys/djtypes.h>
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+#define MB_CUR_MAX __dj_mb_cur_max
+#ifndef NULL
+#define NULL 0
+#endif
+#define RAND_MAX 2147483647
+
+#define _MAX_DRIVE 26
+#define _MAX_FNAME 100
+#define _MAX_EXT 100
+#define _MAX_DIR 26
+#define _MAX_PATH 250
+
+
+extern int errno;
+extern int __dj_mb_cur_max;
+
+extern char ** environ;
+
+
+typedef struct {
+ int quot;
+ int rem;
+} div_t;
+
+typedef struct {
+ long quot;
+ long rem;
+} ldiv_t;
+
+#include <internal/types.h>
+#ifndef _WCHAR_T_
+#define _WCHAR_T_
+#define _WCHAR_T
+ typedef int wchar_t;
+#endif
+
+
+void abort(void) __attribute__((noreturn));
+int abs(int _i);
+int atexit(void (*_func)(void));
+double atof(const char *_s);
+int atoi(const char *_s);
+long atol(const char *_s);
+void * bsearch(const void *_key, const void *_base, size_t _nelem,
+ size_t _size, int (*_cmp)(const void *_ck, const void *_ce));
+void * calloc(size_t _nelem, size_t _size);
+div_t div(int _numer, int _denom);
+void exit(int _status) __attribute__((noreturn));
+void free(void *_ptr);
+char * getenv(const char *_name);
+long labs(long _i);
+ldiv_t ldiv(long _numer, long _denom);
+void * malloc(size_t _size);
+int mblen(const char *_s, size_t _n);
+size_t mbstowcs(wchar_t *_wcs, const char *_s, size_t _n);
+int mbtowc(wchar_t *_pwc, const char *_s, size_t _n);
+void qsort(void *_base, size_t _nelem, size_t _size,
+ int (*_cmp)(const void *_e1, const void *_e2));
+int rand(void);
+void * realloc(void *_ptr, size_t _size);
+void srand(unsigned _seed);
+double strtod(const char *_s, char **_endptr);
+long strtol(const char *_s, char **_endptr, int _base);
+unsigned long strtoul(const char *_s, char **_endptr, int _base);
+int system(const char *_s);
+size_t wcstombs(char *_s, const wchar_t *_wcs, size_t _n);
+int wctomb(char *_s, wchar_t _wchar);
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _POSIX_SOURCE
+
+typedef struct {
+ long long quot;
+ long long rem;
+} lldiv_t;
+
+void * alloca(size_t _size);
+long double _atold(const char *_s);
+long long atoll(const char *_s);
+void cfree(void *_ptr);
+char * getpass(const char *_prompt);
+int getlongpass(const char *_prompt, char *_buffer, int _max_len);
+char * itoa(int value, char *buffer, int radix);
+long long llabs(long long _i);
+lldiv_t lldiv(long long _numer, long long _denom);
+int putenv(const char *_val);
+int setenv(const char *_var, const char *_val, int _replace);
+double _strtold(const char *_s, char **_endptr);
+long strtoll(const char *_s, char **_endptr, int _base);
+unsigned long strtoull(const char *_s, char **_endptr, int _base);
+void swab(const void *from, void *to, int nbytes);
+
+#ifndef alloca
+#define alloca __builtin_alloca
+#endif
+
+/* BSD Random Number Generator */
+char * initstate (unsigned _seed, char *_arg_state, int _n);
+char * setstate(char *_arg_state);
+long random(void);
+int srandom(int _seed);
+
+
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifndef __dj_ENFORCE_FUNCTION_CALLS
+#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__dj_include_stdlib_h_ */
extern "C" {
#endif
+#define __kernel_size_t size_t
char * ___strtok; // removed extern specifier 02-06-98, BD
extern void * memscan(void *,int,__kernel_size_t);
extern int memcmp(const void *,const void *,__kernel_size_t);
+char *strerror( int errnum );
+char *_strerror( const char *string );
+
+// obsolete
+int strcasecmp (const char* sz1, const char* sz2);
+int strncasecmp (const char* sz1, const char* sz2, size_t sizeMaxCompare);
+
/*
* Include machine specific inline routines
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#ifndef __dj_include_time_h_
+#define __dj_include_time_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+/* 65536(tics/hour) / 3600(sec/hour) * 5(scale) = 91.02
+ The 5 is to make it a whole number (18.2*5=91) so that
+ floating point ops aren't required to use it. */
+#define CLOCKS_PER_SEC 91
+
+#include <sys/djtypes.h>
+#include <internal/types.h>
+#ifndef NULL
+#define NULL 0
+#endif
+__DJ_clock_t
+#undef __DJ_clock_t
+#define __DJ_clock_t
+//__DJ_size_t
+#undef __DJ_size_t
+#define __DJ_size_t
+__DJ_time_t
+#undef __DJ_time_t
+#define __DJ_time_t
+
+
+#ifndef _TM_DEFINED
+struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ char *tm_zone;
+ int tm_gmtoff;
+};
+#define _TM_DEFINED
+#endif
+
+char * asctime(const struct tm *_tptr);
+clock_t clock(void);
+char * ctime(const time_t *_cal);
+double difftime(time_t _t1, time_t _t0);
+struct tm * gmtime(const time_t *_tod);
+struct tm * localtime(const time_t *_tod);
+time_t mktime(struct tm *_tptr);
+size_t strftime(char *_s, size_t _n, const char *_format, const struct tm *_tptr);
+time_t time(time_t *_tod);
+
+#ifndef __STRICT_ANSI__
+
+#define CLK_TCK CLOCKS_PER_SEC
+
+extern char *tzname[2];
+
+void tzset(void);
+
+#ifndef _POSIX_SOURCE
+
+//#define tm_zone __tm_zone
+//#define tm_gmtoff __tm_gmtoff
+
+struct timeval {
+ time_t tv_sec;
+ long tv_usec;
+};
+
+struct timezone {
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+
+#include <sys/types.h>
+
+typedef long long uclock_t;
+#define UCLOCKS_PER_SEC 1193180
+
+int gettimeofday(struct timeval *_tp, struct timezone *_tzp);
+unsigned long rawclock(void);
+int select(int _nfds, fd_set *_readfds, fd_set *_writefds, fd_set *_exceptfds, struct timeval *_timeout);
+int settimeofday(struct timeval *_tp, ...);
+uclock_t uclock(void);
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifndef __dj_ENFORCE_FUNCTION_CALLS
+#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__dj_include_time_h_ */
--- /dev/null
+/*
+ * Adapted from linux for the reactos kernel, march 1998 -- David Welch
+ * Added wide character string functions, june 1998 -- Boudewijn Dekker
+ * Removed extern specifier from ___wcstok, june 1998 -- Boudewijn Dekker
+ * Added wcsicmp and wcsnicmp -- Boudewijn Dekker
+ */
+
+#include <internal/types.h>
+
+#ifndef _LINUX_WSTRING_H_
+#define _LINUX_WSTRING_H_
+
+
+
+#ifndef _WCHAR_T_
+#define _WCHAR_T_
+#define _WCHAR_T
+ typedef unsigned short wchar_t;
+#endif
+#define Aa_Difference (L'A'-L'a')
+
+#define towupper(c) (((c>=L'a') && (c<=L'z')) ? c+Aa_Difference : c)
+#define towlower(c) (((c>=L'A') && (c<=L'Z')) ? c-Aa_Difference : c)
+
+//obsolete
+wchar_t wtolower(wchar_t c );
+wchar_t wtoupper(wchar_t c );
+
+
+#define iswlower(c) ((c) >= L'a' && (c) <= L'z')
+#define iswupper(c) ((c) >= L'A' && (c) <= L'Z')
+
+#define iswdigit(c) ((c) >= L'0' && (c) <= L'9')
+#define iswxdigit(c) (((c) >= L'0' && (c) <= L'9') || ((c) >= L'A' && (c) <= L'F') || ((c) >= L'a' && (c) <= L'f') )
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//wchar_t * ___wcstok = NULL;
+wchar_t * wcscpy(wchar_t *,const wchar_t *);
+wchar_t * wcsncpy(wchar_t *,const wchar_t *, size_t);
+wchar_t * wcscat(wchar_t *, const wchar_t *);
+wchar_t * wcsncat(wchar_t *, const wchar_t *, size_t);
+int wcscmp(const wchar_t *,const wchar_t *);
+int wcsncmp(const wchar_t *,const wchar_t *,size_t);
+wchar_t* wcschr(const wchar_t* str, wchar_t ch);
+wchar_t * wcsrchr(const wchar_t *,wchar_t);
+wchar_t * wcspbrk(const wchar_t *,const wchar_t *);
+wchar_t * wcstok(wchar_t *,const wchar_t *);
+wchar_t * wcsstr(const wchar_t *,const wchar_t *);
+size_t wcslen(const wchar_t * s);
+size_t wcsnlen(const wchar_t * s, size_t count);
+int wcsicmp(const wchar_t* cs,const wchar_t * ct);
+int wcsnicmp(const wchar_t* cs,const wchar_t * ct, size_t count);
+size_t wcsspn(const wchar_t *str,const wchar_t *accept);
+size_t wcscspn(const wchar_t *str,const wchar_t *reject);
+wchar_t *wcsrev(wchar_t *s);
+wchar_t *wcsstr(const wchar_t *s,const wchar_t *b);
+wchar_t *wcsdup(const wchar_t *ptr);
+wchar_t *wcsupr(wchar_t *x);
+wchar_t * wcslwr(wchar_t *x);
+
+//obsolete
+size_t wstrlen(const wchar_t * s);
+int wcscmpi (const wchar_t* ws1, const wchar_t* ws2);
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
-/*\r
- * Adapted from linux for the reactos kernel, march 1998 -- David Welch\r
- * Added wide character string functions, june 1998 -- Boudewijn Dekker\r
- * Removed extern specifier from ___wcstok, june 1998 -- Boudewijn Dekker\r
- * Added wcsicmp and wcsnicmp -- Boudewijn Dekker\r
- */\r
-\r
-#ifndef _LINUX_WSTRING_H_\r
-#define _LINUX_WSTRING_H_\r
-\r
-#include <types.h> /* for size_t */\r
-\r
-typedef unsigned short wchar_t;\r
-\r
-#ifndef NULL\r
-#define NULL ((void *) 0)\r
-#endif\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-wchar_t* wstrdup(const wchar_t* src);\r
-extern wchar_t * ___wcstok;\r
-extern wchar_t * wcscpy(wchar_t *,const wchar_t *);\r
-extern wchar_t * wcsncpy(wchar_t *,const wchar_t *, __kernel_size_t);\r
-extern wchar_t * wcscat(wchar_t *, const wchar_t *);\r
-extern wchar_t * wcsncat(wchar_t *, const wchar_t *, __kernel_size_t);\r
-extern int wcscmp(const wchar_t *,const wchar_t *);\r
-extern int wcsncmp(const wchar_t *,const wchar_t *,__kernel_size_t);\r
-wchar_t* wcschr(const wchar_t* str, wchar_t ch);\r
-extern wchar_t * wcsrchr(const wchar_t *,wchar_t);\r
-extern wchar_t * wcspbrk(const wchar_t *,const wchar_t *);\r
-extern wchar_t * wcstok(wchar_t *,const wchar_t *);\r
-extern wchar_t * wcsstr(const wchar_t *,const wchar_t *);\r
-extern size_t wcsnlen(const wchar_t * s, size_t count);\r
-extern int wcsicmp(const wchar_t* cs,const wchar_t * ct);\r
-extern int wcsnicmp(const wchar_t* cs,const wchar_t * ct, size_t count);\r
-extern size_t wcscspn(const wchar_t *, const wchar_t *);\r
-extern size_t wcslen(const wchar_t *);\r
-extern size_t wcsspn(const wchar_t *, const wchar_t *);\r
-\r
-extern unsigned long wstrlen(PWSTR);\r
-WCHAR wtoupper(WCHAR c);\r
-WCHAR wtolower(WCHAR c);\r
- \r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif \r
-\r
+// this file is obsolete
+#include <wchar.h>
+
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/cputs.c
+ * PURPOSE: Writes a character to stdout
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+#include <windows.h>
+#include <conio.h>
+#include <string.h>
+
+int cputs(const char *_str)
+{
+ int len = strlen(_str);
+ int written = 0;
+ if ( !WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),_str,len,&written,NULL))
+ return -1;
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/getch.c
+ * PURPOSE: Writes a character to stdout
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+#include <conio.h>
+#include <stdio.h>
+#include <windows.h>
+
+extern int char_avail;
+extern int ungot_char;
+
+int getch( void )
+{
+ return _getch();
+}
+
+int
+_getch(void)
+{
+
+ DWORD NumberOfCharsRead;
+ char c;
+ if (char_avail)
+ {
+ c = ungot_char;
+ char_avail = 0;
+ }
+ else
+ {
+
+ if( !ReadFile(filehnd(stdin->_file), &c,1,&NumberOfCharsRead ,NULL))
+ return -1;
+
+ }
+ printk("%c",c);
+ return c;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/getche.c
+ * PURPOSE: Reads a character from stdin
+ * PROGRAMER: DJ Delorie
+ Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+
+#include <process.h>
+#include <conio.h>
+
+
+extern int char_avail;
+int
+getche(void)
+{
+ if (char_avail)
+ /*
+ * We don't know, wether the ungot char was already echoed
+ * we assume yes (for example in cscanf, probably the only
+ * place where ungetch is ever called.
+ * There is no way to check for this really, because
+ * ungetch could have been called with a character that
+ * hasn't been got by a conio function.
+ * We don't echo again.
+ */
+ return(getch());
+ return (_putch(getch()));
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/putch.c
+ * PURPOSE: Writes a character to stdout
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+#include <conio.h>
+#include <windows.h>
+
+int _putch( int c )
+{
+ DWORD NumberOfCharsWritten;
+ if ( WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),&c,1,&NumberOfCharsWritten,NULL) ) {
+ return -1;
+ }
+
+ return NumberOfCharsWritten;
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/ungetch.c
+ * PURPOSE: Ungets a character from stdin
+ * PROGRAMER: DJ Delorie
+ Boudewijn Dekker [ Adapted from djgpp libc ]
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+
+#include <process.h>
+#define EOF -1
+
+int char_avail = 0;
+char ungot_char = 0;
+
+
+int
+ungetch(int c)
+{
+ if (char_avail)
+ return(EOF);
+ ungot_char = c;
+ char_avail = 1;
+ return(c);
+}
\ No newline at end of file
--- /dev/null
+# Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
+TOP=../..
+
+SRC += ct_flags.c
+SRC += ct_lower.c
+SRC += ct_upper.c
+SRC += isalnum.c
+SRC += isalpha.c
+SRC += isascii.c
+SRC += iscntrl.c
+SRC += isdigit.c
+SRC += isgraph.c
+SRC += islower.c
+SRC += isprint.c
+SRC += ispunct.c
+SRC += isspace.c
+SRC += isupper.c
+SRC += isxdigit.c
+SRC += toascii.c
+SRC += tolower.c
+SRC += toupper.c
+
+include $(TOP)/../makefile.inc
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/ungetch.c
+ * PURPOSE: Ungets a character from stdin
+ * PROGRAMER: DJ Delorie
+ Boudewijn Dekker [ Adapted from djgpp libc ]
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+#include <stdlib.h>
+
+double
+atof(const char *ascii)
+{
+ return strtod(ascii, 0);
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/ungetch.c
+ * PURPOSE: Ungets a character from stdin
+ * PROGRAMER: DJ Delorie
+ Boudewijn Dekker [ Adapted from djgpp libc ]
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+
+#include <stdlib.h>
+
+int
+atoi(const char *str)
+{
+ return (int)strtol(str, 0, 10);
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/atol.c
+ * PURPOSE: Ungets a character from stdin
+ * PROGRAMER: DJ Delorie
+ Boudewijn Dekker [ Adapted from djgpp libc ]
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+long
+atol(const char *str)
+{
+ return strtol(str, 0, 10);
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/ungetch.c
+ * PURPOSE: Ungets a character from stdin
+ * PROGRAMER: DJ Delorie
+ Boudewijn Dekker [ Adapted from djgpp libc ]
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+long double
+_atold(const char *ascii)
+{
+ return _strtold(ascii, 0);
+}
--- /dev/null
+
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+#include <inlines/ctype.ha>
+
+unsigned short __dj_ctype_flags[] = {
+ 0, /* CTRL+?, 0xffff */
+ __dj_ISCNTRL, /* CTRL+@, 0x00 */
+ __dj_ISCNTRL, /* CTRL+A, 0x01 */
+ __dj_ISCNTRL, /* CTRL+B, 0x02 */
+ __dj_ISCNTRL, /* CTRL+C, 0x03 */
+ __dj_ISCNTRL, /* CTRL+D, 0x04 */
+ __dj_ISCNTRL, /* CTRL+E, 0x05 */
+ __dj_ISCNTRL, /* CTRL+F, 0x06 */
+ __dj_ISCNTRL, /* CTRL+G, 0x07 */
+ __dj_ISCNTRL, /* CTRL+H, 0x08 */
+ __dj_ISCNTRL | __dj_ISSPACE, /* CTRL+I, 0x09 */
+ __dj_ISCNTRL | __dj_ISSPACE, /* CTRL+J, 0x0a */
+ __dj_ISCNTRL | __dj_ISSPACE, /* CTRL+K, 0x0b */
+ __dj_ISCNTRL | __dj_ISSPACE, /* CTRL+L, 0x0c */
+ __dj_ISCNTRL | __dj_ISSPACE, /* CTRL+M, 0x0d */
+ __dj_ISCNTRL, /* CTRL+N, 0x0e */
+ __dj_ISCNTRL, /* CTRL+O, 0x0f */
+ __dj_ISCNTRL, /* CTRL+P, 0x10 */
+ __dj_ISCNTRL, /* CTRL+Q, 0x11 */
+ __dj_ISCNTRL, /* CTRL+R, 0x12 */
+ __dj_ISCNTRL, /* CTRL+S, 0x13 */
+ __dj_ISCNTRL, /* CTRL+T, 0x14 */
+ __dj_ISCNTRL, /* CTRL+U, 0x15 */
+ __dj_ISCNTRL, /* CTRL+V, 0x16 */
+ __dj_ISCNTRL, /* CTRL+W, 0x17 */
+ __dj_ISCNTRL, /* CTRL+X, 0x18 */
+ __dj_ISCNTRL, /* CTRL+Y, 0x19 */
+ __dj_ISCNTRL, /* CTRL+Z, 0x1a */
+ __dj_ISCNTRL, /* CTRL+[, 0x1b */
+ __dj_ISCNTRL, /* CTRL+\, 0x1c */
+ __dj_ISCNTRL, /* CTRL+], 0x1d */
+ __dj_ISCNTRL, /* CTRL+^, 0x1e */
+ __dj_ISCNTRL, /* CTRL+_, 0x1f */
+ __dj_ISPRINT | __dj_ISSPACE, /* ` ', 0x20 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `!', 0x21 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* 0x22 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `#', 0x23 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `$', 0x24 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `%', 0x25 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `&', 0x26 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* 0x27 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `(', 0x28 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `)', 0x29 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `*', 0x2a */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `+', 0x2b */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `,', 0x2c */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `-', 0x2d */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `.', 0x2e */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `/', 0x2f */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `0', 0x30 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `1', 0x31 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `2', 0x32 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `3', 0x33 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `4', 0x34 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `5', 0x35 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `6', 0x36 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `7', 0x37 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `8', 0x38 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `9', 0x39 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `:', 0x3a */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `;', 0x3b */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `<', 0x3c */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `=', 0x3d */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `>', 0x3e */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `?', 0x3f */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `@', 0x40 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `A', 0x41 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `B', 0x42 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `C', 0x43 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `D', 0x44 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `E', 0x45 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `F', 0x46 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `G', 0x47 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `H', 0x48 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `I', 0x49 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `J', 0x4a */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `K', 0x4b */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `L', 0x4c */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `M', 0x4d */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `N', 0x4e */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `O', 0x4f */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `P', 0x50 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `Q', 0x51 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `R', 0x52 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `S', 0x53 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `T', 0x54 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `U', 0x55 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `V', 0x56 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `W', 0x57 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `X', 0x58 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `Y', 0x59 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `Z', 0x5a */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `[', 0x5b */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* 0x5c */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `]', 0x5d */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `^', 0x5e */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `_', 0x5f */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* 0x60 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `a', 0x61 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `b', 0x62 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `c', 0x63 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `d', 0x64 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `e', 0x65 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `f', 0x66 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `g', 0x67 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `h', 0x68 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `i', 0x69 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `j', 0x6a */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `k', 0x6b */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `l', 0x6c */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `m', 0x6d */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `n', 0x6e */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `o', 0x6f */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `p', 0x70 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `q', 0x71 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `r', 0x72 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `s', 0x73 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `t', 0x74 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `u', 0x75 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `v', 0x76 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `w', 0x77 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `x', 0x78 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `y', 0x79 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `z', 0x7a */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `{', 0x7b */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `|', 0x7c */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `}', 0x7d */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `~', 0x7e */
+ __dj_ISCNTRL, /* 0x7f */
+ 0, /* 0x80 */
+ 0, /* 0x81 */
+ 0, /* 0x82 */
+ 0, /* 0x83 */
+ 0, /* 0x84 */
+ 0, /* 0x85 */
+ 0, /* 0x86 */
+ 0, /* 0x87 */
+ 0, /* 0x88 */
+ 0, /* 0x89 */
+ 0, /* 0x8a */
+ 0, /* 0x8b */
+ 0, /* 0x8c */
+ 0, /* 0x8d */
+ 0, /* 0x8e */
+ 0, /* 0x8f */
+ 0, /* 0x90 */
+ 0, /* 0x91 */
+ 0, /* 0x92 */
+ 0, /* 0x93 */
+ 0, /* 0x94 */
+ 0, /* 0x95 */
+ 0, /* 0x96 */
+ 0, /* 0x97 */
+ 0, /* 0x98 */
+ 0, /* 0x99 */
+ 0, /* 0x9a */
+ 0, /* 0x9b */
+ 0, /* 0x9c */
+ 0, /* 0x9d */
+ 0, /* 0x9e */
+ 0, /* 0x9f */
+ 0, /* 0xa0 */
+ 0, /* 0xa1 */
+ 0, /* 0xa2 */
+ 0, /* 0xa3 */
+ 0, /* 0xa4 */
+ 0, /* 0xa5 */
+ 0, /* 0xa6 */
+ 0, /* 0xa7 */
+ 0, /* 0xa8 */
+ 0, /* 0xa9 */
+ 0, /* 0xaa */
+ 0, /* 0xab */
+ 0, /* 0xac */
+ 0, /* 0xad */
+ 0, /* 0xae */
+ 0, /* 0xaf */
+ 0, /* 0xb0 */
+ 0, /* 0xb1 */
+ 0, /* 0xb2 */
+ 0, /* 0xb3 */
+ 0, /* 0xb4 */
+ 0, /* 0xb5 */
+ 0, /* 0xb6 */
+ 0, /* 0xb7 */
+ 0, /* 0xb8 */
+ 0, /* 0xb9 */
+ 0, /* 0xba */
+ 0, /* 0xbb */
+ 0, /* 0xbc */
+ 0, /* 0xbd */
+ 0, /* 0xbe */
+ 0, /* 0xbf */
+ 0, /* 0xc0 */
+ 0, /* 0xc1 */
+ 0, /* 0xc2 */
+ 0, /* 0xc3 */
+ 0, /* 0xc4 */
+ 0, /* 0xc5 */
+ 0, /* 0xc6 */
+ 0, /* 0xc7 */
+ 0, /* 0xc8 */
+ 0, /* 0xc9 */
+ 0, /* 0xca */
+ 0, /* 0xcb */
+ 0, /* 0xcc */
+ 0, /* 0xcd */
+ 0, /* 0xce */
+ 0, /* 0xcf */
+ 0, /* 0xd0 */
+ 0, /* 0xd1 */
+ 0, /* 0xd2 */
+ 0, /* 0xd3 */
+ 0, /* 0xd4 */
+ 0, /* 0xd5 */
+ 0, /* 0xd6 */
+ 0, /* 0xd7 */
+ 0, /* 0xd8 */
+ 0, /* 0xd9 */
+ 0, /* 0xda */
+ 0, /* 0xdb */
+ 0, /* 0xdc */
+ 0, /* 0xdd */
+ 0, /* 0xde */
+ 0, /* 0xdf */
+ 0, /* 0xe0 */
+ 0, /* 0xe1 */
+ 0, /* 0xe2 */
+ 0, /* 0xe3 */
+ 0, /* 0xe4 */
+ 0, /* 0xe5 */
+ 0, /* 0xe6 */
+ 0, /* 0xe7 */
+ 0, /* 0xe8 */
+ 0, /* 0xe9 */
+ 0, /* 0xea */
+ 0, /* 0xeb */
+ 0, /* 0xec */
+ 0, /* 0xed */
+ 0, /* 0xee */
+ 0, /* 0xef */
+ 0, /* 0xf0 */
+ 0, /* 0xf1 */
+ 0, /* 0xf2 */
+ 0, /* 0xf3 */
+ 0, /* 0xf4 */
+ 0, /* 0xf5 */
+ 0, /* 0xf6 */
+ 0, /* 0xf7 */
+ 0, /* 0xf8 */
+ 0, /* 0xf9 */
+ 0, /* 0xfa */
+ 0, /* 0xfb */
+ 0, /* 0xfc */
+ 0, /* 0xfd */
+ 0, /* 0xfe */
+ 0, /* 0xff */
+};
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+#include <inlines/ctype.ha>
+
+unsigned char __dj_ctype_tolower[] = {
+ 0x00,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+#include <inlines/ctype.ha>
+
+unsigned char __dj_ctype_toupper[] = {
+ 0x00,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/putch.c
+ * PURPOSE: Writes a character to stdout
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+#include <ctype.h>
+
+#undef isalnum
+int isalnum(int c)
+{
+ return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'));
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/putch.c
+ * PURPOSE: Checks if a character is alphanumeric
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+
+#include <ctype.h>
+
+#undef isalpha
+int isalpha(int c)
+{
+ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/getch.c
+ * PURPOSE: Writes a character to stdout
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+
+#include <ctype.h>
+
+#undef isascii
+int isascii(int c)
+{
+ return ( (unsigned)(c) <0x80 ) ;
+}
+
+int __isascii(int c)
+{
+ return ( (unsigned)(c) <0x80 ) ;
+}
+
+
+
+
+
+
+
+
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+
+#undef iscntrl
+int iscntrl(int c)
+{
+ return ((c >=0x00 && c <= 0x1f) || c == 0x7f) ;
+}
--- /dev/null
+
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/ctype/iscsym.c
+ * PURPOSE: Writes a character to stdout
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+
+#include <ctype.h>
+
+#undef iscsym
+int
+iscsym (int c)
+{
+ return __iscsym(c);
+}
+
+int
+__iscsym (int c)
+{
+ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || ( c == '_' );
+}
+
+#undef iscsymf
+int
+iscsymf (int c)
+{
+ return __iscsymf(c);
+}
+
+int
+__iscsymf (int c)
+{
+ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || ( c == '_' );
+}
+
+
--- /dev/null
+
+#include <ctype.h>
+
+
+
+#define __dj_ISUPPER 0x1
+#define __dj_ISLOWER 0x2
+#define __dj_ISDIGIT 0x4
+#define __dj_ISSPACE 0x8
+#define __dj_ISPUNCT 0x10
+#define __dj_ISCNTRL 0x20
+#define __dj_ISBLANK 0x40
+#define __dj_ISXDIGIT 0x80
+#define __dj_ISPRINT (__dj_ISBLANK|__dj_ISPUNCT|__dj_ISUPPER|__dj_ISLOWER|__dj_ISDIGIT)
+#define __dj_ISALNUM (__dj_ISUPPER|__dj_ISLOWER|__dj_ISDIGIT)
+#define __dj_ISGRAPH (__dj_ISPUNCT|__dj_ISUPPER|__dj_ISLOWER|__dj_ISDIGIT)
+#define __dj_ISALPHA (0x0100|__dj_ISUPPER|__dj_ISLOWER)
+
+
+unsigned short __dj_ctype_flags[] = {
+ 0, /* CTRL+?, 0xffff */
+ __dj_ISCNTRL, /* CTRL+@, 0x00 */
+ __dj_ISCNTRL, /* CTRL+A, 0x01 */
+ __dj_ISCNTRL, /* CTRL+B, 0x02 */
+ __dj_ISCNTRL, /* CTRL+C, 0x03 */
+ __dj_ISCNTRL, /* CTRL+D, 0x04 */
+ __dj_ISCNTRL, /* CTRL+E, 0x05 */
+ __dj_ISCNTRL, /* CTRL+F, 0x06 */
+ __dj_ISCNTRL, /* CTRL+G, 0x07 */
+ __dj_ISCNTRL, /* CTRL+H, 0x08 */
+ __dj_ISCNTRL | __dj_ISSPACE, /* CTRL+I, 0x09 */
+ __dj_ISCNTRL | __dj_ISSPACE, /* CTRL+J, 0x0a */
+ __dj_ISCNTRL | __dj_ISSPACE, /* CTRL+K, 0x0b */
+ __dj_ISCNTRL | __dj_ISSPACE, /* CTRL+L, 0x0c */
+ __dj_ISCNTRL | __dj_ISSPACE, /* CTRL+M, 0x0d */
+ __dj_ISCNTRL, /* CTRL+N, 0x0e */
+ __dj_ISCNTRL, /* CTRL+O, 0x0f */
+ __dj_ISCNTRL, /* CTRL+P, 0x10 */
+ __dj_ISCNTRL, /* CTRL+Q, 0x11 */
+ __dj_ISCNTRL, /* CTRL+R, 0x12 */
+ __dj_ISCNTRL, /* CTRL+S, 0x13 */
+ __dj_ISCNTRL, /* CTRL+T, 0x14 */
+ __dj_ISCNTRL, /* CTRL+U, 0x15 */
+ __dj_ISCNTRL, /* CTRL+V, 0x16 */
+ __dj_ISCNTRL, /* CTRL+W, 0x17 */
+ __dj_ISCNTRL, /* CTRL+X, 0x18 */
+ __dj_ISCNTRL, /* CTRL+Y, 0x19 */
+ __dj_ISCNTRL, /* CTRL+Z, 0x1a */
+ __dj_ISCNTRL, /* CTRL+[, 0x1b */
+ __dj_ISCNTRL, /* CTRL+\, 0x1c */
+ __dj_ISCNTRL, /* CTRL+], 0x1d */
+ __dj_ISCNTRL, /* CTRL+^, 0x1e */
+ __dj_ISCNTRL, /* CTRL+_, 0x1f */
+ __dj_ISPRINT | __dj_ISSPACE, /* ` ', 0x20 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `!', 0x21 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* 0x22 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `#', 0x23 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `$', 0x24 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `%', 0x25 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `&', 0x26 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* 0x27 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `(', 0x28 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `)', 0x29 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `*', 0x2a */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `+', 0x2b */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `,', 0x2c */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `-', 0x2d */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `.', 0x2e */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `/', 0x2f */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `0', 0x30 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `1', 0x31 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `2', 0x32 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `3', 0x33 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `4', 0x34 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `5', 0x35 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `6', 0x36 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `7', 0x37 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `8', 0x38 */
+ __dj_ISALNUM | __dj_ISDIGIT | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISXDIGIT, /* `9', 0x39 */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `:', 0x3a */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `;', 0x3b */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `<', 0x3c */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `=', 0x3d */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `>', 0x3e */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `?', 0x3f */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `@', 0x40 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `A', 0x41 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `B', 0x42 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `C', 0x43 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `D', 0x44 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `E', 0x45 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER | __dj_ISXDIGIT, /* `F', 0x46 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `G', 0x47 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `H', 0x48 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `I', 0x49 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `J', 0x4a */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `K', 0x4b */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `L', 0x4c */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `M', 0x4d */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `N', 0x4e */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `O', 0x4f */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `P', 0x50 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `Q', 0x51 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `R', 0x52 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `S', 0x53 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `T', 0x54 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `U', 0x55 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `V', 0x56 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `W', 0x57 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `X', 0x58 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `Y', 0x59 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISPRINT | __dj_ISUPPER, /* `Z', 0x5a */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `[', 0x5b */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* 0x5c */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `]', 0x5d */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `^', 0x5e */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `_', 0x5f */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* 0x60 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `a', 0x61 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `b', 0x62 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `c', 0x63 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `d', 0x64 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `e', 0x65 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT | __dj_ISXDIGIT, /* `f', 0x66 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `g', 0x67 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `h', 0x68 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `i', 0x69 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `j', 0x6a */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `k', 0x6b */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `l', 0x6c */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `m', 0x6d */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `n', 0x6e */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `o', 0x6f */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `p', 0x70 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `q', 0x71 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `r', 0x72 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `s', 0x73 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `t', 0x74 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `u', 0x75 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `v', 0x76 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `w', 0x77 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `x', 0x78 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `y', 0x79 */
+ __dj_ISALNUM | __dj_ISALPHA | __dj_ISGRAPH | __dj_ISLOWER | __dj_ISPRINT, /* `z', 0x7a */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `{', 0x7b */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `|', 0x7c */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `}', 0x7d */
+ __dj_ISGRAPH | __dj_ISPRINT | __dj_ISPUNCT, /* `~', 0x7e */
+ __dj_ISCNTRL, /* 0x7f */
+ 0, /* 0x80 */
+ 0, /* 0x81 */
+ 0, /* 0x82 */
+ 0, /* 0x83 */
+ 0, /* 0x84 */
+ 0, /* 0x85 */
+ 0, /* 0x86 */
+ 0, /* 0x87 */
+ 0, /* 0x88 */
+ 0, /* 0x89 */
+ 0, /* 0x8a */
+ 0, /* 0x8b */
+ 0, /* 0x8c */
+ 0, /* 0x8d */
+ 0, /* 0x8e */
+ 0, /* 0x8f */
+ 0, /* 0x90 */
+ 0, /* 0x91 */
+ 0, /* 0x92 */
+ 0, /* 0x93 */
+ 0, /* 0x94 */
+ 0, /* 0x95 */
+ 0, /* 0x96 */
+ 0, /* 0x97 */
+ 0, /* 0x98 */
+ 0, /* 0x99 */
+ 0, /* 0x9a */
+ 0, /* 0x9b */
+ 0, /* 0x9c */
+ 0, /* 0x9d */
+ 0, /* 0x9e */
+ 0, /* 0x9f */
+ 0, /* 0xa0 */
+ 0, /* 0xa1 */
+ 0, /* 0xa2 */
+ 0, /* 0xa3 */
+ 0, /* 0xa4 */
+ 0, /* 0xa5 */
+ 0, /* 0xa6 */
+ 0, /* 0xa7 */
+ 0, /* 0xa8 */
+ 0, /* 0xa9 */
+ 0, /* 0xaa */
+ 0, /* 0xab */
+ 0, /* 0xac */
+ 0, /* 0xad */
+ 0, /* 0xae */
+ 0, /* 0xaf */
+ 0, /* 0xb0 */
+ 0, /* 0xb1 */
+ 0, /* 0xb2 */
+ 0, /* 0xb3 */
+ 0, /* 0xb4 */
+ 0, /* 0xb5 */
+ 0, /* 0xb6 */
+ 0, /* 0xb7 */
+ 0, /* 0xb8 */
+ 0, /* 0xb9 */
+ 0, /* 0xba */
+ 0, /* 0xbb */
+ 0, /* 0xbc */
+ 0, /* 0xbd */
+ 0, /* 0xbe */
+ 0, /* 0xbf */
+ 0, /* 0xc0 */
+ 0, /* 0xc1 */
+ 0, /* 0xc2 */
+ 0, /* 0xc3 */
+ 0, /* 0xc4 */
+ 0, /* 0xc5 */
+ 0, /* 0xc6 */
+ 0, /* 0xc7 */
+ 0, /* 0xc8 */
+ 0, /* 0xc9 */
+ 0, /* 0xca */
+ 0, /* 0xcb */
+ 0, /* 0xcc */
+ 0, /* 0xcd */
+ 0, /* 0xce */
+ 0, /* 0xcf */
+ 0, /* 0xd0 */
+ 0, /* 0xd1 */
+ 0, /* 0xd2 */
+ 0, /* 0xd3 */
+ 0, /* 0xd4 */
+ 0, /* 0xd5 */
+ 0, /* 0xd6 */
+ 0, /* 0xd7 */
+ 0, /* 0xd8 */
+ 0, /* 0xd9 */
+ 0, /* 0xda */
+ 0, /* 0xdb */
+ 0, /* 0xdc */
+ 0, /* 0xdd */
+ 0, /* 0xde */
+ 0, /* 0xdf */
+ 0, /* 0xe0 */
+ 0, /* 0xe1 */
+ 0, /* 0xe2 */
+ 0, /* 0xe3 */
+ 0, /* 0xe4 */
+ 0, /* 0xe5 */
+ 0, /* 0xe6 */
+ 0, /* 0xe7 */
+ 0, /* 0xe8 */
+ 0, /* 0xe9 */
+ 0, /* 0xea */
+ 0, /* 0xeb */
+ 0, /* 0xec */
+ 0, /* 0xed */
+ 0, /* 0xee */
+ 0, /* 0xef */
+ 0, /* 0xf0 */
+ 0, /* 0xf1 */
+ 0, /* 0xf2 */
+ 0, /* 0xf3 */
+ 0, /* 0xf4 */
+ 0, /* 0xf5 */
+ 0, /* 0xf6 */
+ 0, /* 0xf7 */
+ 0, /* 0xf8 */
+ 0, /* 0xf9 */
+ 0, /* 0xfa */
+ 0, /* 0xfb */
+ 0, /* 0xfc */
+ 0, /* 0xfd */
+ 0, /* 0xfe */
+ 0, /* 0xff */
+};
+
+
+
+int _isctype(int c, int t)
+{
+
+ return (__dj_ctype_flags[(c & 0xFF)]&t == t );
+}
+
+unsigned short *_pctype = __dj_ctype_flags;
+
+int __mb_cur_max = 2;
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+
+#undef isdigit
+int isdigit(int c)
+{
+ return (c >= '0' && c <= '9');
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+
+#undef isgraph
+int isgraph(int c)
+{
+ return 0;
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+
+#undef islower
+int islower(int c)
+{
+ return (c >= 'a' && c <= 'z');
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+
+#undef isprint
+int isprint(int c)
+{
+ return c;
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+
+#undef ispunct
+int ispunct(int c)
+{
+ return (c == '.');
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+
+#undef isspace
+int isspace(int c)
+{
+ return ( c == ' ' || c == '\t' );
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+
+#undef isupper
+int isupper(int c)
+{
+ return (c >= 'A' && c <= 'Z' );
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+
+#undef isxdigit
+int isxdigit(int c)
+{
+ return (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f') || ( c >= '0' && c >= '9' );
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+#include <ctype.h>
+
+#undef toascii
+int toascii(int c)
+{
+ return (c);
+}
+
+int __toascii(int c)
+{
+ return (c);
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+#undef tolower
+int tolower(int c)
+{
+ return (c >= 'A' && c <= 'Z') ? c - ( 'A' - 'a' ) : c;
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+
+#undef toupper
+int toupper(int c)
+{
+ return (c >= 'a' && c <= 'z') ? c + 'A' - 'a' : c;
+}
--- /dev/null
+#include <direct.h>
+#include <windows.h>
+#include <ctype.h>
+
+char _SetCurrentDirectory(char *dir);
+int _GetCurrentDirectory(int count,char *buffer);
+
+#undef chdir
+int chdir( const char *_path )
+{
+ return _chdir(_path);
+}
+
+int _chdir( const char *_path )
+{
+ if ( _path[1] == ':')
+ _chdrive(tolower(_path[0] - 'a')+1);
+ if ( !SetCurrentDirectory((char *)_path) )
+ return -1;
+
+ return 0;
+}
+
+
+
--- /dev/null
+#include <direct.h>
+#include <stdlib.h>
+#include <windows.h>
+
+int cur_drive = 0;
+
+
+
+int _chdrive( int drive )
+{
+ char d[3];
+ if (!( drive >= 1 && drive <= 26 ))
+ return -1;
+
+ if ( cur_drive != drive ) {
+ cur_drive = drive;
+ d[0] = toupper(cur_drive + '@');
+ d[1] = ':';
+ d[2] = 0;
+ SetCurrentDirectory(d);
+ }
+
+
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+#include <windows.h>
+#include <direct.h>
+#include <stdlib.h>
+
+
+
+#undef getcwd
+char *getcwd( char *buffer, int maxlen )
+{
+ return _getcwd(buffer,maxlen);
+}
+
+char *_getcwd( char *buffer, int maxlen )
+{
+ char *cwd;
+ int len;
+ if ( buffer == NULL ) {
+ cwd = malloc(MAX_PATH);
+ len = MAX_PATH;
+ }
+ else {
+ cwd = buffer;
+ len = maxlen;
+ }
+
+
+ if ( GetCurrentDirectory(len,cwd) == 0 )
+ return NULL;
+
+
+ return cwd;
+}
+
--- /dev/null
+#include <direct.h>
+#include <windows.h>
+#include <ctype.h>
+
+
+unsigned int _getdiskfree(unsigned int _drive, struct _diskfree_t *_diskspace)
+{
+ char RootPathName[10];
+ RootPathName[0] = toupper(_drive +'@');
+ RootPathName[1] = ':';
+ RootPathName[2] = '\\';
+ RootPathName[3] = 0;
+ if ( _diskspace == NULL )
+ return 0;
+
+ if ( !GetDiskFreeSpaceA(RootPathName,&_diskspace->sectors_per_cluster,&_diskspace->bytes_per_sector,&_diskspace->avail_clusters,&_diskspace->total_clusters ) )
+ return 0;
+ return _diskspace->avail_clusters;
+}
\ No newline at end of file
--- /dev/null
+#include <direct.h>
+#include <windows.h>
+
+extern int cur_drive;
+
+
+
+int _getdrive( void )
+{
+ char Buffer[MAX_PATH];
+
+ if ( cur_drive == 0 ) {
+ GetCurrentDirectory(MAX_PATH,Buffer);
+ cur_drive = toupper(Buffer[0] - '@');
+ }
+
+ return cur_drive;
+}
--- /dev/null
+#include <direct.h>
+#include <windows.h>
+
+#undef mkdir
+int mkdir( const char *_path )
+{
+ return _mkdir(_path);
+}
+int _mkdir( const char *_path )
+{
+ if (!CreateDirectoryA(_path,NULL))
+ return -1;
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+#include <direct.h>
+#include <windows.h>
+
+#undef rmdir
+int rmdir( const char *_path )
+{
+ return _rmdir(_path);
+}
+
+int _rmdir( const char *_path )
+{
+ if (!RemoveDirectoryA(_path))
+ return -1;
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * dirent.c
+ *
+ * Derived from DIRLIB.C by Matt J. Weinstein
+ * This note appears in the DIRLIB.H
+ * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
+ *
+ * Updated by Jeremy Bettis <jeremy@hksys.com>
+ * Significantly revised and rewinddir, seekdir and telldir added by Colin
+ * Peters <colin@fu.is.saga-u.ac.jp>
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:43 $
+ *
+ */
+
+#include <stdlib.h>
+/* #include <ctype.h> */
+#include <errno.h>
+#include <string.h>
+#include <dir.h>
+#include <direct.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+
+#define SUFFIX "*"
+#define SLASH "\\"
+#define streq(a,b) (strcmp(a,b)==0)
+
+/*
+ * opendir
+ *
+ * Returns a pointer to a DIR structure appropriately filled in to begin
+ * searching a directory.
+ */
+DIR*
+opendir(const char* szPath)
+{
+ DIR* nd;
+ struct stat statDir;
+
+ errno = 0;
+
+ if (!szPath)
+ {
+ errno = EFAULT;
+ return (DIR*) 0;
+ }
+
+ if (szPath[0] == '\0')
+ {
+ errno = ENOTDIR;
+ return (DIR*) 0;
+ }
+
+ /* Attempt to determine if the given path really is a directory. */
+ if (_stat (szPath, &statDir))
+ {
+ /* Error, stat should have set an error value. */
+ return (DIR*) 0;
+ }
+
+ if (!S_ISDIR(statDir.st_mode))
+ {
+ /* Error, stat reports not a directory. */
+ errno = ENOTDIR;
+ return (DIR*) 0;
+ }
+
+ /* Allocate enough space to store DIR structure and the complete
+ * directory path given. */
+ nd = (DIR*) malloc (sizeof(DIR) + strlen(szPath) + strlen(SLASH) +
+ strlen(SUFFIX));
+
+ if (!nd)
+ {
+ /* Error, out of memory. */
+ errno = ENOMEM;
+ return (DIR*) 0;
+ }
+
+ /* Create the search expression. */
+ strcpy(nd->dd_name, szPath);
+
+ /* Add on a slash if the path does not end with one. */
+ if (nd->dd_name[0] != '\0' &&
+ nd->dd_name[strlen(nd->dd_name)-1] != '/' &&
+ nd->dd_name[strlen(nd->dd_name)-1] != '\\')
+ {
+ strcat(nd->dd_name, SLASH);
+ }
+
+ /* Add on the search pattern */
+ strcat(nd->dd_name, SUFFIX);
+
+ /* Initialize handle to -1 so that a premature closedir doesn't try
+ * to call _findclose on it. */
+ nd->dd_handle = -1;
+
+ /* Initialize the status. */
+ nd->dd_stat = 0;
+
+ /* Initialize the dirent structure. ino and reclen are invalid under
+ * Win32, and name simply points at the appropriate part of the
+ * findfirst_t structure. */
+ nd->dd_dir.d_ino = 0;
+ nd->dd_dir.d_reclen = 0;
+ nd->dd_dir.d_namlen = 0;
+ nd->dd_dir.d_name = nd->dd_dta.name;
+
+ return nd;
+}
+
+
+/*
+ * readdir
+ *
+ * Return a pointer to a dirent structure filled with the information on the
+ * next entry in the directory.
+ */
+struct dirent *
+readdir( DIR *dirp )
+{
+ errno = 0;
+
+ /* Check for valid DIR struct. */
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return (struct dirent*) 0;
+ }
+
+ if (dirp->dd_dir.d_name != dirp->dd_dta.name)
+ {
+ /* The structure does not seem to be set up correctly. */
+ errno = EINVAL;
+ return (struct dirent*) 0;
+ }
+
+ if (dirp->dd_stat < 0)
+ {
+ /* We have already returned all files in the directory
+ * (or the structure has an invalid dd_stat). */
+ return (struct dirent *) 0;
+ }
+ else if (dirp->dd_stat == 0)
+ {
+ /* We haven't started the search yet. */
+ /* Start the search */
+ dirp->dd_handle = _findfirst(dirp->dd_name, &(dirp->dd_dta));
+
+ if (dirp->dd_handle == -1)
+ {
+ /* Whoops! Seems there are no files in that
+ * directory. */
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ dirp->dd_stat = 1;
+ }
+ }
+ else
+ {
+ /* Get the next search entry. */
+ if (_findnext(dirp->dd_handle, &(dirp->dd_dta)))
+ {
+ /* We are off the end or otherwise error. */
+ _findclose (dirp->dd_handle);
+ dirp->dd_handle = -1;
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ /* Update the status to indicate the correct
+ * number. */
+ dirp->dd_stat++;
+ }
+ }
+
+ if (dirp->dd_stat > 0)
+ {
+ /* Successfully got an entry. Everything about the file is
+ * already appropriately filled in except the length of the
+ * file name. */
+ dirp->dd_dir.d_namlen = strlen(dirp->dd_dir.d_name);
+ return &dirp->dd_dir;
+ }
+
+ return (struct dirent*) 0;
+}
+
+
+/*
+ * closedir
+ *
+ * Frees up resources allocated by opendir.
+ */
+int
+closedir (DIR* dirp)
+{
+ int rc;
+
+ errno = 0;
+ rc = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+
+ if (dirp->dd_handle != -1)
+ {
+ rc = _findclose(dirp->dd_handle);
+ }
+
+ /* Delete the dir structure. */
+ free (dirp);
+
+ return rc;
+}
+
+/*
+ * rewinddir
+ *
+ * Return to the beginning of the directory "stream". We simply call findclose
+ * and then reset things like an opendir.
+ */
+void
+rewinddir (DIR* dirp)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return;
+ }
+
+ if (dirp->dd_handle != -1)
+ {
+ _findclose(dirp->dd_handle);
+ }
+
+ dirp->dd_handle = -1;
+ dirp->dd_stat = 0;
+}
+
+/*
+ * telldir
+ *
+ * Returns the "position" in the "directory stream" which can be used with
+ * seekdir to go back to an old entry. We simply return the value in stat.
+ */
+long
+telldir (DIR* dirp)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+ return dirp->dd_stat;
+}
+
+/*
+ * seekdir
+ *
+ * Seek to an entry previously returned by telldir. We rewind the directory
+ * and call readdir repeatedly until either dd_stat is the position number
+ * or -1 (off the end). This is not perfect, in that the directory may
+ * have changed while we weren't looking. But that is probably the case with
+ * any such system.
+ */
+void
+seekdir (DIR* dirp, long lPos)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return;
+ }
+
+ if (lPos < -1)
+ {
+ /* Seeking to an invalid position. */
+ errno = EINVAL;
+ return;
+ }
+ else if (lPos == -1)
+ {
+ /* Seek past end. */
+ if (dirp->dd_handle != -1)
+ {
+ _findclose (dirp->dd_handle);
+ }
+ dirp->dd_handle = -1;
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ /* Rewind and read forward to the appropriate index. */
+ rewinddir (dirp);
+
+ while ((dirp->dd_stat < lPos) && readdir(dirp))
+ ;
+ }
+}
+
--- /dev/null
+#include <float.h>
+
+void _fpreset( void )
+{
+ return;
+}
+
--- /dev/null
+#include <io.h>
+#include <windows.h>
+
+#define F_OK 0x01
+#define R_OK 0x02
+#define W_OK 0x04
+#define X_OK 0x08
+#define D_OK 0x10
+
+int access(const char *_path, int _amode)
+{
+ return _access(_path,_amode);
+}
+
+int _access( const char *_path, int _amode )
+{
+ DWORD Attributes = GetFileAttributesA(_path);
+
+ if ( Attributes == -1 )
+ return -1;
+
+ if ( _amode & W_OK == W_OK ) {
+ if ( (Attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY )
+ return -1;
+ }
+ if ( _amode & D_OK == D_OK ) {
+ if ( (Attributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY )
+ return 0;
+ }
+
+ return 0;
+
+}
\ No newline at end of file
--- /dev/null
+#include <io.h>
+#include <windows.h>
+#include <libc/file.h>
+
+
+int close(int _fd)
+{
+ return _close(_fd);
+}
+
+int _close(int _fd)
+{
+ CloseHandle(filehnd(_fd));
+ return __fileno_close(_fd);
+
+}
\ No newline at end of file
--- /dev/null
+#include <io.h>
+#include <fcntl.h>
+
+#undef creat
+int creat(const char *filename, int mode)
+{
+ return open(filename,_O_CREAT|_O_TRUNC,mode);
+}
--- /dev/null
+#include <windows.h>
+#include <io.h>
+
+#undef dup
+int dup( int handle )
+{
+ return _dup(handle);
+}
+
+int _dup( int handle )
+{
+ return _open_osfhandle(filehnd(handle), 0666);
+}
\ No newline at end of file
--- /dev/null
+#include <windows.h>
+#include <io.h>
+
+#undef dup2
+int dup2( int handle1, int handle2 )
+{
+ return _dup2(handle1,handle2);
+}
+
+
+int _dup2( int handle1, int handle2 )
+{
+ return __fileno_dup2( handle1, handle2 );
+}
\ No newline at end of file
--- /dev/null
+#include <windows.h>
+#include <io.h>
+#include <string.h>
+#include <libc/file.h>
+
+//UnixTimeToFileTime
+//FileTimeToUnixTime
+/*
+ * DOS file system functions
+ *
+ * Copyright 1993 Erik Bos
+ * Copyright 1996 Alexandre Julliard
+ */
+
+
+void UnixTimeToFileTime( time_t unix_time, FILETIME *filetime, DWORD remainder );
+time_t FileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder );
+
+
+long _findfirst(char *_name, struct _finddata_t *result)
+{
+ WIN32_FIND_DATA FindFileData;
+ char dir[MAX_PATH];
+
+
+ long hFindFile;
+
+ if ( _name == NULL || _name[0] == 0 ) {
+ GetCurrentDirectory(MAX_PATH,dir);
+ strcat(dir,"\\*.*");
+ }
+ else
+ strcpy(dir,_name);
+ hFindFile = FindFirstFile( dir, &FindFileData );
+ result->attrib = FindFileData.dwFileAttributes;
+
+
+ result->time_create = FileTimeToUnixTime( &FindFileData.ftCreationTime,NULL);
+ result->time_access = FileTimeToUnixTime( &FindFileData.ftLastAccessTime,NULL);
+ result->time_write = FileTimeToUnixTime( &FindFileData.ftLastWriteTime,NULL);
+ result->size = FindFileData.nFileSizeLow;
+ strncpy(result->name,&FindFileData.cFileName,260);
+ return hFindFile;
+}
+
+int _findnext(long handle, struct _finddata_t *result)
+{
+ WIN32_FIND_DATA FindFileData;
+ if (handle == -1 )
+ return -1;
+
+ if ( !FindNextFile(handle, &FindFileData ) )
+ return -1;
+
+ result->attrib = FindFileData.dwFileAttributes;
+ result->time_create = FileTimeToUnixTime( &FindFileData.ftCreationTime,NULL);
+ result->time_access = FileTimeToUnixTime( &FindFileData.ftLastAccessTime,NULL);
+ result->time_write = FileTimeToUnixTime( &FindFileData.ftLastWriteTime,NULL);
+ result->size = FindFileData.nFileSizeLow;
+ strncpy(result->name,&FindFileData.cFileName,260);
+ return 0;
+}
+int _findclose(long handle)
+{
+ return FindClose(handle);
+}
+
+
+/***********************************************************************
+ * DOSFS_UnixTimeToFileTime
+ *
+ * Convert a Unix time to FILETIME format.
+ * The FILETIME structure is a 64-bit value representing the number of
+ * 100-nanosecond intervals since January 1, 1601, 0:00.
+ * 'remainder' is the nonnegative number of 100-ns intervals
+ * corresponding to the time fraction smaller than 1 second that
+ * couldn't be stored in the time_t value.
+ */
+void UnixTimeToFileTime( time_t unix_time, FILETIME *filetime,
+ DWORD remainder )
+{
+ /* NOTES:
+
+ CONSTANTS:
+ The time difference between 1 January 1601, 00:00:00 and
+ 1 January 1970, 00:00:00 is 369 years, plus the leap years
+ from 1604 to 1968, excluding 1700, 1800, 1900.
+ This makes (1968 - 1600) / 4 - 3 = 89 leap days, and a total
+ of 134774 days.
+
+ Any day in that period had 24 * 60 * 60 = 86400 seconds.
+
+ The time difference is 134774 * 86400 * 10000000, which can be written
+ 116444736000000000
+ 27111902 * 2^32 + 3577643008
+ 413 * 2^48 + 45534 * 2^32 + 54590 * 2^16 + 32768
+
+ If you find that these constants are buggy, please change them in all
+ instances in both conversion functions.
+
+ VERSIONS:
+ There are two versions, one of them uses long long variables and
+ is presumably faster but not ISO C. The other one uses standard C
+ data types and operations but relies on the assumption that negative
+ numbers are stored as 2's complement (-1 is 0xffff....). If this
+ assumption is violated, dates before 1970 will not convert correctly.
+ This should however work on any reasonable architecture where WINE
+ will run.
+
+ DETAILS:
+
+ Take care not to remove the casts. I have tested these functions
+ (in both versions) for a lot of numbers. I would be interested in
+ results on other compilers than GCC.
+
+ The operations have been designed to account for the possibility
+ of 64-bit time_t in future UNICES. Even the versions without
+ internal long long numbers will work if time_t only is 64 bit.
+ A 32-bit shift, which was necessary for that operation, turned out
+ not to work correctly in GCC, besides giving the warning. So I
+ used a double 16-bit shift instead. Numbers are in the ISO version
+ represented by three limbs, the most significant with 32 bit, the
+ other two with 16 bit each.
+
+ As the modulo-operator % is not well-defined for negative numbers,
+ negative divisors have been avoided in DOSFS_FileTimeToUnixTime.
+
+ There might be quicker ways to do this in C. Certainly so in
+ assembler.
+
+ Claus Fischer, fischer@iue.tuwien.ac.at
+ */
+
+
+
+
+ unsigned long a0; /* 16 bit, low bits */
+ unsigned long a1; /* 16 bit, medium bits */
+ unsigned long a2; /* 32 bit, high bits */
+
+ /* Copy the unix time to a2/a1/a0 */
+ a0 = unix_time & 0xffff;
+ a1 = (unix_time >> 16) & 0xffff;
+ /* This is obsolete if unix_time is only 32 bits, but it does not hurt.
+ Do not replace this by >> 32, it gives a compiler warning and it does
+ not work. */
+ a2 = (unix_time >= 0 ? (unix_time >> 16) >> 16 :
+ ~((~unix_time >> 16) >> 16));
+
+ /* Multiply a by 10000000 (a = a2/a1/a0)
+ Split the factor into 10000 * 1000 which are both less than 0xffff. */
+ a0 *= 10000;
+ a1 = a1 * 10000 + (a0 >> 16);
+ a2 = a2 * 10000 + (a1 >> 16);
+ a0 &= 0xffff;
+ a1 &= 0xffff;
+
+ a0 *= 1000;
+ a1 = a1 * 1000 + (a0 >> 16);
+ a2 = a2 * 1000 + (a1 >> 16);
+ a0 &= 0xffff;
+ a1 &= 0xffff;
+
+ /* Add the time difference and the remainder */
+ a0 += 32768 + (remainder & 0xffff);
+ a1 += 54590 + (remainder >> 16 ) + (a0 >> 16);
+ a2 += 27111902 + (a1 >> 16);
+ a0 &= 0xffff;
+ a1 &= 0xffff;
+
+ /* Set filetime */
+ filetime->dwLowDateTime = (a1 << 16) + a0;
+ filetime->dwHighDateTime = a2;
+}
+
+
+/***********************************************************************
+ * DOSFS_FileTimeToUnixTime
+ *
+ * Convert a FILETIME format to Unix time.
+ * If not NULL, 'remainder' contains the fractional part of the filetime,
+ * in the range of [0..9999999] (even if time_t is negative).
+ */
+time_t FileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder )
+{
+ /* Read the comment in the function DOSFS_UnixTimeToFileTime. */
+
+ unsigned long a0; /* 16 bit, low bits */
+ unsigned long a1; /* 16 bit, medium bits */
+ unsigned long a2; /* 32 bit, high bits */
+ unsigned long r; /* remainder of division */
+ unsigned int carry; /* carry bit for subtraction */
+ int negative; /* whether a represents a negative value */
+
+ /* Copy the time values to a2/a1/a0 */
+ a2 = (unsigned long)filetime->dwHighDateTime;
+ a1 = ((unsigned long)filetime->dwLowDateTime ) >> 16;
+ a0 = ((unsigned long)filetime->dwLowDateTime ) & 0xffff;
+
+ /* Subtract the time difference */
+ if (a0 >= 32768 ) a0 -= 32768 , carry = 0;
+ else a0 += (1 << 16) - 32768 , carry = 1;
+
+ if (a1 >= 54590 + carry) a1 -= 54590 + carry, carry = 0;
+ else a1 += (1 << 16) - 54590 - carry, carry = 1;
+
+ a2 -= 27111902 + carry;
+
+ /* If a is negative, replace a by (-1-a) */
+ negative = (a2 >= ((unsigned long)1) << 31);
+ if (negative)
+ {
+ /* Set a to -a - 1 (a is a2/a1/a0) */
+ a0 = 0xffff - a0;
+ a1 = 0xffff - a1;
+ a2 = ~a2;
+ }
+
+ /* Divide a by 10000000 (a = a2/a1/a0), put the rest into r.
+ Split the divisor into 10000 * 1000 which are both less than 0xffff. */
+ a1 += (a2 % 10000) << 16;
+ a2 /= 10000;
+ a0 += (a1 % 10000) << 16;
+ a1 /= 10000;
+ r = a0 % 10000;
+ a0 /= 10000;
+
+ a1 += (a2 % 1000) << 16;
+ a2 /= 1000;
+ a0 += (a1 % 1000) << 16;
+ a1 /= 1000;
+ r += (a0 % 1000) * 10000;
+ a0 /= 1000;
+
+ /* If a was negative, replace a by (-1-a) and r by (9999999 - r) */
+ if (negative)
+ {
+ /* Set a to -a - 1 (a is a2/a1/a0) */
+ a0 = 0xffff - a0;
+ a1 = 0xffff - a1;
+ a2 = ~a2;
+
+ r = 9999999 - r;
+ }
+
+ if (remainder) *remainder = r;
+
+ /* Do not replace this by << 32, it gives a compiler warning and it does
+ not work. */
+ return ((((time_t)a2) << 16) << 16) + (a1 << 16) + a0;
+
+}
+
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <fcntl.h>
+#include <io.h>
+
+#undef _fmode
+int _fmode = O_TEXT;
+
+unsigned int fmode_dll = &_fmode;
--- /dev/null
+#include <io.h>
+
+#undef isatty
+
+int isatty( int handle )
+{
+ return (handle & 3);
+}
\ No newline at end of file
--- /dev/null
+#include <windows.h>
+#include <io.h>
+#include <libc/file.h>
+
+#undef lseek
+long lseek(int _fildes, long _offset, int _whence)
+{
+ return _lseek(_fildes,_offset,_whence);
+}
+
+long _lseek(int _fildes, long _offset, int _whence)
+{
+ //return _llseek(filehnd(_fildes),_offset,_whence);
+}
+
+
+
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/io/mktemp.c
+ * PURPOSE: Makes a temp file based on a template
+ * PROGRAMER: DJ Delorie
+ Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Appropriated for the Reactos Kernel
+ */
+
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+#include <stdio.h>
+#include <string.h>
+#include <io.h>
+
+
+char *
+mktemp (char *_template)
+{
+ static int count = 0;
+ char *cp, *dp;
+ int i, len, xcount, loopcnt;
+
+
+
+ len = strlen (_template);
+ cp = _template + len;
+
+ xcount = 0;
+ while (xcount < 6 && cp > _template && cp[-1] == 'X')
+ xcount++, cp--;
+
+ if (xcount) {
+ dp = cp;
+ while (dp > _template && dp[-1] != '/' && dp[-1] != '\\' && dp[-1] != ':')
+ dp--;
+
+ /* Keep the first characters of the template, but turn the rest into
+ Xs. */
+ while (cp > dp + 8 - xcount) {
+ *--cp = 'X';
+ xcount = (xcount >= 6) ? 6 : 1 + xcount;
+ }
+
+ /* If dots occur too early -- squash them. */
+ while (dp < cp) {
+ if (*dp == '.') *dp = 'a';
+ dp++;
+ }
+
+ /* Try to add ".tmp" to the filename. Truncate unused Xs. */
+ if (cp + xcount + 3 < _template + len)
+ strcpy (cp + xcount, ".tmp");
+ else
+ cp[xcount] = 0;
+
+ /* This loop can run up to 2<<(5*6) times, or about 10^9 times. */
+ for (loopcnt = 0; loopcnt < (1 << (5 * xcount)); loopcnt++) {
+ int c = count++;
+ for (i = 0; i < xcount; i++, c >>= 5)
+ cp[i] = "abcdefghijklmnopqrstuvwxyz012345"[c & 0x1f];
+ if (_access(_template,0) == -1)
+ return _template;
+ }
+ }
+
+ /* Failure: truncate the template and return NULL. */
+ *_template = 0;
+ return 0;
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/cputs.c
+ * PURPOSE: Opens a file and translates handles to fileno
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+#include <io.h>
+#include <windows.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <libc/file.h>
+#include <string.h>
+#include <share.h>
+
+typedef struct _fileno_modes_type
+{
+ HANDLE hFile;
+ int mode;
+ int fd;
+} fileno_modes_type;
+
+extern fileno_modes_type *fileno_modes;
+
+char __is_text_file(FILE *p) {
+ return (!((p)->_flag&_IOSTRG) && (fileno_modes[(p)->_file].mode&O_TEXT));
+}
+
+
+extern int maxfno;
+
+
+int __fileno_alloc(HANDLE hFile, int mode);
+
+// fixme
+#undef open
+int open(const char *_path, int _oflag,...)
+{
+ return _open(_path,_oflag);
+}
+
+int _open(const char *_path, int _oflag,...)
+{
+
+ HANDLE hFile;
+ DWORD dwDesiredAccess = 0;
+ DWORD dwShareMode = 0;
+ DWORD dwCreationDistribution = 0;
+ DWORD dwFlagsAndAttributes = 0;
+
+ if (( _oflag & _S_IREAD ) == _S_IREAD)
+ dwShareMode = FILE_SHARE_READ;
+ else if ( ( _oflag & _S_IWRITE) == _S_IWRITE ) {
+ dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ }
+
+/*
+
+_O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
+_O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
+
+*/
+ if (( _oflag & _O_RDWR ) == _O_RDWR )
+ dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ;
+ else if (( _oflag & O_RDONLY ) == O_RDONLY )
+ dwDesiredAccess |= GENERIC_READ;
+ else if (( _oflag & _O_WRONLY ) == _O_WRONLY )
+ dwDesiredAccess |= GENERIC_WRITE;
+
+ if (( _oflag & _S_IREAD ) == _S_IREAD )
+ dwShareMode |= FILE_SHARE_READ;
+
+ if (( _oflag & _S_IWRITE ) == _S_IWRITE )
+ dwShareMode |= FILE_SHARE_WRITE;
+
+ if (( _oflag & (_O_CREAT | _O_EXCL ) ) == (_O_CREAT | _O_EXCL) )
+ dwCreationDistribution |= CREATE_NEW;
+
+ else if (( _oflag & (O_TRUNC | O_CREAT ) ) == (O_TRUNC | O_CREAT) )
+ dwCreationDistribution |= CREATE_ALWAYS;
+
+ else if (( _oflag & _O_APPEND ) == _O_APPEND )
+ dwCreationDistribution |= OPEN_EXISTING;
+ else if (( _oflag & _O_CREAT ) == _O_CREAT )
+ dwCreationDistribution |= OPEN_ALWAYS;
+ else
+ dwCreationDistribution |= OPEN_EXISTING;
+
+// if (( _oflag & _O_TRUNC ) == _O_TRUNC )
+// dwCreationDistribution |= TRUNCATE_EXISTING;
+
+ if (( _oflag & _O_RANDOM ) == _O_RANDOM )
+ dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
+ if (( _oflag & _O_SEQUENTIAL ) == _O_SEQUENTIAL )
+ dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
+
+ if (( _oflag & _O_TEMPORARY ) == _O_TEMPORARY )
+ dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
+
+ if (( _oflag & _O_SHORT_LIVED ) == _O_SHORT_LIVED )
+ dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
+
+ hFile = CreateFileA(
+ _path,
+ dwDesiredAccess,
+ dwShareMode,
+ NULL,
+ dwCreationDistribution,
+ dwFlagsAndAttributes,
+ NULL
+ );
+ if ( hFile == (HANDLE)-1 )
+ return -1;
+ return __fileno_alloc(hFile,_oflag);
+
+// _O_APPEND Moves file pointer to end of file before every write operation.
+
+}
+
+
+fileno_modes_type *fileno_modes = NULL;
+
+int maxfno = 5;
+int minfno = 5;
+
+
+int
+__fileno_alloc(HANDLE hFile, int mode)
+{
+
+ int i;
+ /* Check for bogus values */
+ if (hFile < 0)
+ return -1;
+
+ for(i=minfno;i<maxfno;i++) {
+ if (fileno_modes[i].fd == -1 ) {
+ fileno_modes[i].fd = i;
+ fileno_modes[i].mode = 666;
+ fileno_modes[i].hFile = hFile;
+ return i;
+ }
+ }
+
+
+ /* See if we need to expand the tables. Check this BEFORE it might fail,
+ so that when we hit the count'th request, we've already up'd it. */
+ if ( i == maxfno)
+ {
+ int oldcount = maxfno;
+ fileno_modes_type *old_fileno_modes = fileno_modes;
+ maxfno += 255;
+ fileno_modes = (fileno_modes_type *)malloc(maxfno * sizeof(fileno_modes_type));
+ if ( old_fileno_modes != NULL )
+ memcpy(fileno_modes, old_fileno_modes, oldcount * sizeof(fileno_modes_type));
+ memset(fileno_modes + oldcount, 0, (maxfno-oldcount)*sizeof(fileno_modes));
+ free ( old_fileno_modes );
+
+ }
+
+ /* Fill in the value */
+ fileno_modes[i].fd = i;
+ fileno_modes[i].mode = _fmode;
+ fileno_modes[i].hFile = hFile;
+ return i;
+}
+
+void *filehnd(int fileno)
+{
+
+
+
+ if ( fileno < 0 )
+ return (void *)-1;
+#define STD_AUX_HANDLE 3
+#define STD_PRINTER_HANDLE 4
+
+ switch(fileno)
+ {
+ case 0:
+ return GetStdHandle(STD_INPUT_HANDLE);
+ case 1:
+ return GetStdHandle(STD_OUTPUT_HANDLE);
+ case 2:
+ return GetStdHandle(STD_ERROR_HANDLE);
+ case 3:
+ return GetStdHandle(STD_AUX_HANDLE);
+ case 4:
+ return GetStdHandle(STD_PRINTER_HANDLE);
+ default:
+ break;
+ }
+
+ if ( fileno >= maxfno )
+ return (void *)-1;
+
+ if ( fileno_modes[fileno].fd == -1 )
+ return (void *)-1;
+ return fileno_modes[fileno].hFile;
+}
+
+int __fileno_dup2( int handle1, int handle2 )
+{
+ if ( handle1 >= maxfno )
+ return -1;
+
+ if ( handle1 < 0 )
+ return -1;
+ if ( handle2 >= maxfno )
+ return -1;
+
+ if ( handle2 < 0 )
+ return -1;
+
+ memcpy(&fileno_modes[handle1],&fileno_modes[handle2],sizeof(fileno_modes));
+
+
+ return handle1;
+}
+
+int __fileno_setmode(int _fd, int _newmode)
+{
+ int m;
+ if ( _fd < 0 )
+ return -1;
+
+ if ( _fd >= maxfno )
+ return -1;
+
+ m = fileno_modes[_fd].mode;
+ fileno_modes[_fd].mode = _newmode;
+ return m;
+}
+
+int __fileno_close(int _fd)
+{
+ if ( _fd < 0 )
+ return -1;
+
+ if ( _fd >= maxfno )
+ return -1;
+
+ fileno_modes[_fd].fd = -1;
+ fileno_modes[_fd].hFile = (HANDLE)-1;
+
+}
+
+int _open_osfhandle (void *osfhandle, int flags )
+{
+ return __fileno_alloc((HANDLE)osfhandle, flags);
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/io/read.c
+ * PURPOSE: Reads a file
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+#include <io.h>
+#include <windows.h>
+
+size_t read(int _fd, void *_buf, size_t _nbyte)
+{
+ return _read(_fd,_buf,_nbyte);
+}
+size_t _read(int _fd, void *_buf, size_t _nbyte)
+{
+ size_t _rbyte;
+ if ( !ReadFile(filehnd(_fd),_buf,_nbyte,&_rbyte,NULL) ) {
+ printf("%d\n",GetLastError());
+ return -1;
+ }
+
+ return _rbyte;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/io/setmode.c
+ * PURPOSE: Sets the file translation mode
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+
+#include <io.h>
+#include <stdio.h>
+#include <libc/file.h>
+
+#undef setmode
+int setmode(int _fd, int _newmode)
+{
+ return _setmode(_fd, _newmode);
+}
+
+int _setmode(int _fd, int _newmode)
+{
+ return __fileno_setmode(_fd, _newmode);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/io/unlink.c
+ * PURPOSE: Deletes a file
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+#include <windows.h>
+#include <io.h>
+
+int unlink( const char *filename )
+{
+ return _unlink(filename);
+}
+
+int _unlink( const char *filename )
+{
+ if ( !DeleteFile(filename) )
+ return -1;
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/io/write.c
+ * PURPOSE: Writes to a file
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+#include <io.h>
+#include <windows.h>
+#include <libc/file.h>
+
+int write(int _fd, const void *_buf,int _nbyte)
+{
+ return _write(_fd,_buf,_nbyte);
+}
+
+size_t _write(int _fd, const void *_buf, size_t _nbyte)
+{
+ size_t _wbyte;
+ if ( !WriteFile(filehnd(_fd),_buf,_nbyte,&_wbyte,NULL) ) {
+ printf("%d\n",GetLastError());
+ return -1;
+ }
+ return _wbyte;
+}
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#ifndef __dj_include_libc_atexit_h__
+#define __dj_include_libc_dosexec_h__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _POSIX_SOURCE
+
+struct __atexit {
+ struct __atexit *__next;
+ void (*__function)(void);
+};
+
+extern struct __atexit *__atexit_ptr;
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifndef __dj_ENFORCE_FUNCTION_CALLS
+#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __dj_include_libc_dosexec_h__ */
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#ifndef __dj_include_libc_file_h__
+#define __dj_include_libc_file_h__
+
+#include <stdio.h>
+#include <fcntl.h>
+
+
+//#include <libc/dosio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _POSIX_SOURCE
+
+#ifndef _IORMONCL
+#define _IORMONCL 004000 /* remove on close, for temp files */
+#endif
+/* if _flag & _IORMONCL, ._name_to_remove needs freeing */
+
+#ifndef _IOUNGETC
+#define _IOUNGETC 010000 /* there is an ungetc'ed character in the buffer */
+#endif
+
+int _flsbuf(int, FILE*);
+int _filbuf(FILE *);
+void _fwalk(void (*)(FILE *));
+
+
+
+char __is_text_file(FILE *p);
+
+int _doprnt(const char *fmt, va_list args, FILE *f);
+int _doscan(FILE *iop, const char *fmt, void **argp);
+
+void *filehnd(int fileno);
+int __fileno_dup2( int handle1, int handle2 );
+int __fileno_setmode(int _fd, int _newmode);
+int __fileno_close(int _fd);
+
+#undef fileno
+#define fileno(f) (f->_file)
+#undef feof
+#define feof(f) (((f)->_flag&_IOEOF)!=0)
+#undef ferror
+#define ferror(f) (((f)->_flag&_IOERR)!=0)
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifndef __dj_ENFORCE_FUNCTION_CALLS
+#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __dj_include_libc_file_h__ */
all: crtdll.a
+
+CTYPE_OBJECTS = ctype/ct_flags.o ctype/ct_lower.o ctype/ct_upper.o ctype/isalnum.o \
+ ctype/isalpha.o ctype/isascii.o ctype/iscntrl.o ctype/isdigit.o ctype/isgraph.o \
+ ctype/islower.o ctype/isprint.o ctype/ispunct.o ctype/isspace.o ctype/isupper.o \
+ ctype/isxdigit.o ctype/toascii.o ctype/tolower.o ctype/toupper.o
+
+CONIO_OBJECTS = conio/cputs.o conio/getch.o conio/getche.o conio/putch.o conio/ungetch.o
+
+DIRECT_OBJECTS = direct/chdir.o direct/chdrive.o direct/getcwd.o direct/getdrive.o \
+ direct/rmdir.o direct/mkdir.o direct/getdfree.o
+
+MISC_OBJECTS = misc/sleep.o misc/crt1.o misc/getargs.o misc/crtfmode.o
+
STRING_OBJECTS = string/memchr.o string/memcmp.o string/strcat.o \
string/strchr.o string/strcmp.o string/strcoll.o \
string/strcpy.o string/strcspn.o string/memcpy.o \
string/strncpy.o string/strpbrk.o string/strrchr.o \
string/strspn.o string/strstr.o string/strtok.o \
string/strxfrm.o string/memmove.o string/memset.o \
- string/strdup.o
+ string/strdup.o string/strlwr.o string/strupr.o \
+ string/str_old.o string/strerror.o
+
+WCHAR_OBJECTS = wchar/wcscat.o wchar/wcschr.o wchar/wcscmp.o \
+ wchar/wcscoll.o wchar/wcscpy.o wchar/wcscspn.o \
+ wchar/wcsdup.o wchar/wcsicmp.o wchar/wcslen.o \
+ wchar/wcslwr.o wchar/wcsncat.o wchar/wcsncmp.o \
+ wchar/wcsncpy.o
+
+STDIO_OBJECTS = stdio/vsprintf.o stdio/getenv.o stdio/doprnt.o stdio/doscan.o \
+ stdio/puts.o stdio/fclose.o stdio/feof.o stdio/ferror.o \
+ stdio/fflush.o stdio/fgetc.o stdio/fgetpos.o stdio/fgets.o stdio/flsbuf.o \
+ stdio/fopen.o stdio/fprintf.o stdio/fputc.o stdio/fputs.o \
+ stdio/fread.o stdio/freopen.o stdio/fscanf.o stdio/fseek.o \
+ stdio/fsetpos.o stdio/ftell.o stdio/fwalk.o stdio/fwrite.o stdio/getc.o \
+ stdio/getchar.o stdio/gets.o stdio/getw.o stdio/perror.o stdio/printf.o \
+ stdio/putc.o stdio/putchar.o stdio/puts.o stdio/putw.o \
+ stdio/remove.o stdio/rename.o stdio/rewind.o stdio/allocfil.o\
+ stdio/scanf.o stdio/setbuf.o stdio/setbuffe.o \
+ stdio/setlineb.o stdio/setvbuf.o stdio/sprintf.o stdio/sscanf.o \
+ stdio/stdiohk.o stdio/stdhnd.o stdio/tempnam.o stdio/tmpfile.o stdio/tmpnam.o \
+ stdio/ungetc.o stdio/vfprintf.o stdio/vprintf.o stdio/vsprintf.o
+
+
+IO_OBJECTS = io/access.o io/close.o io/create.o io/dup.o io/dup2.o io/find.o io/isatty.o io/lseek.o \
+ io/open.o io/read.o io/setmode.o io/unlink.o io/write.o io/fmode.o
+
+STDLIB_OBJECTS = stdlib/abort.o stdlib/abs.o stdlib/atexit.o stdlib/atof.o stdlib/atoi.o stdlib/atold.o \
+ stdlib/bsearch.o stdlib/calloc.o stdlib/div.o stdlib/errno.o stdlib/exit.o \
+ stdlib/fullpath.o stdlib/labs.o stdlib/ldiv.o stdlib/llabs.o stdlib/lldiv.o \
+ stdlib/makepath.o stdlib/malloc.o stdlib/putenv.o stdlib/qsort.o \
+ stdlib/rand.o stdlib/senv.o stdlib/splitp.o stdlib/strtod.o stdlib/strtol.o \
+ stdlib/strtoul.o stdlib/strtold.o
+
+PROCESS_OBJECTS = process/spawnl.o process/spawnlp.o process/spawnlpe.o process/spawnvpe.o process/spawnvp.o \
+ process/spawnv.o process/spawnve.o process/spawnle.o process/execl.o process/execlp.o process/execlpe.o \
+ process/execvpe.o process/execvp.o process/execv.o process/execle.o
+
+TIME_OBJECTS = time/ctime.o time/difftime.o time/strftime.o time/time.o
+FLOAT_OBJECTS = float/fpreset.o
-STDIO_OBJECTS = stdio/vsprintf.o
+SYS_STAT_OBJECTS = sys_stat/fstat.o sys_stat/stat.o
-STDLIB_OBJECTS = stdlib/malloc.o
+OBJECTS = $(CTYPE_OBJECTS) $(CONIO_OBJECTS) $(DIRECT_OBJECTS) $(MISC_OBJECTS) \
+ $(STRING_OBJECTS) $(WCHAR_OBJECTS) $(STDIO_OBJECTS) $(STDLIB_OBJECTS) \
+ $(IO_OBJECTS) $(PROCESS_OBJECTS) $(TIME_OBJECTS) $(FLOAT_OBJECTS) \
+ $(SYS_STAT_OBJECTS)
-OBJECTS = $(STRING_OBJECTS) $(STDIO_OBJECTS) $(STDLIB_OBJECTS)
crtdll.a: $(OBJECTS)
- $(AR) rcs crtdll.a $(OBJECTS)
+ $(CC) $(CFLAGS) -c $< -o $@
+ $(AR) vrcs crtdll.a $(OBJECTS)
dummy:
-include ../../rules.mak
+include ../../Rules.mak
--- /dev/null
+long __cdecl ftol(double fl) {
+ return (long)fl;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * noglob.c
+ *
+ * This file defines _CRT_glob to have a value of 0, which will
+ * turn off command line globbing. It is compiled into a separate object
+ * file which you can add to your link line to turn off globbing like
+ * this:
+ *
+ * gcc -o foo.exe foo.o noglob.o
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:43 $
+ *
+ */
+
+int _CRT_glob = 0;
+
--- /dev/null
+/*
+ * CRTfmode.c
+ *
+ * Sets _CRT_fmode to be zero, which will cause _mingw32_init_fmode to leave
+ * all file modes in their default state (basically text mode).
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * THIS FILE IS IN THE PUBLIC DOMAIN.
+ *
+ * Contributers:
+ * Created by Colin Peters <colin@fu.is.saga-u.ac.jp>
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:43 $
+ *
+ */
+
+unsigned int _CRT_fmode = 0;
+
--- /dev/null
+/*
+ * CRTglob.c
+ *
+ * This object file defines _CRT_glob to have a value of -1, which will
+ * turn on command line globbing by default. If you want to turn off
+ * command line globbing include a line
+ *
+ * int _CRT_glob = 0;
+ *
+ * in one of your source modules.
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:43 $
+ *
+ */
+
+int _CRT_glob = -1;
+
--- /dev/null
+/*
+ * CRTinit.c
+ *
+ * A dummy version of _CRT_INIT for MS compatibility. Programs, or more often
+ * dlls, which use the static version of the MSVC run time are supposed to
+ * call _CRT_INIT to initialize the run time library in DllMain. This does
+ * not appear to be necessary when using crtdll or the dll versions of the
+ * MSVC runtime, so the dummy call simply does nothing.
+ *
+ * Contributors:
+ * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAMED. This includes but is not limited to warrenties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:43 $
+ *
+ */
+
+void
+_CRT_INIT ()
+{
+}
+
--- /dev/null
+#include <windows.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+char *acmdln_dll;
+unsigned int commode_dll;
+
+unsigned int fmode_dll;
+unsigned int winmajor_dll;
+unsigned int winminor_dll;
+unsigned int winver_dll;
+unsigned int osver_dll;
+
+#undef __argv
+#undef __argc
+
+char *xargv[1024];
+
+char **__argv = xargv;
+int __argc = 0;
+unsigned int *__argc_dll = &__argc;
+char ***__argv_dll = &__argv;
+
+char *xenv;
+char **_environ;
+char *** _environ_dll = &_environ;
+#undef environ
+char **environ;
+
+
+int __GetMainArgs(int *argc,char ***argv,char **env,int flag)
+{
+ char *cmdline;
+ int i,afterlastspace;
+ DWORD version;
+
+// acmdln_dll = cmdline = strdup( GetCommandLineA() );
+
+ version = GetVersion();
+ osver_dll = version >> 16;
+ winminor_dll = version & 0xFF;
+ winmajor_dll = (version>>8) & 0xFF;
+ winver_dll = ((version >> 8) & 0xFF) + ((version & 0xFF) << 8);
+
+
+ /* missing threading init */
+
+ i=0;
+
+ afterlastspace=0;
+ while (cmdline[i]) {
+ if (cmdline[i]==' ') {
+ __argc++;
+ cmdline[i]='\0';
+ __argv[__argc-1] = strdup( cmdline+afterlastspace);
+ i++;
+ while (cmdline[i]==' ')
+ i++;
+ if (cmdline[i])
+ afterlastspace=i;
+ } else
+ i++;
+ }
+
+ __argc++;
+ cmdline[i]='\0';
+ __argv[__argc-1] = strdup( cmdline+afterlastspace);
+
+
+ *argc = __argc;
+ *argv = __argv;
+
+
+ xenv = GetEnvironmentStringsA();
+ _environ = &xenv;
+ _environ_dll = &_environ;
+ environ = &xenv;
+ env = &xenv;
+ return 0;
+}
+
+int _chkstk()
+{
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * crt1.c
+ *
+ * Source code for the startup proceedures used by all programs. This code
+ * is compiled to make crt0.o, which should be located in the library path.
+ *
+ * This code is part of the Mingw32 package.
+ *
+ * Contributors:
+ * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAMED. This includes but is not limited to warrenties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:43 $
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#include <float.h>
+#include <windows.h>
+
+/* NOTE: The code for initializing the _argv, _argc, and environ variables
+ * has been moved to a separate .c file which is included in both
+ * crt1.c and dllcrt1.c. This means changes in the code don't have to
+ * be manually synchronized, but it does lead to this not-generally-
+ * a-good-idea use of include. */
+#include "init.c"
+
+extern int main(int, char**, char**);
+
+/*
+ * Setup the default file handles to have the _CRT_fmode mode, as well as
+ * any new files created by the user.
+ */
+extern unsigned int _CRT_fmode;
+
+void
+_mingw32_init_fmode ()
+{
+ /* Don't set the file mode if the user hasn't set any value for it. */
+ if (_CRT_fmode)
+ {
+ _fmode = _CRT_fmode;
+
+ /*
+ * This overrides the default file mode settings for stdin,
+ * stdout and stderr. At first I thought you would have to
+ * test with isatty, but it seems that the DOS console at
+ * least is smart enough to handle _O_BINARY stdout and
+ * still display correctly.
+ */
+ if (stdin)
+ {
+ _setmode (_fileno(stdin), _CRT_fmode);
+ }
+ if (stdout)
+ {
+ _setmode (_fileno(stdout), _CRT_fmode);
+ }
+ if (stderr)
+ {
+ _setmode (_fileno(stderr), _CRT_fmode);
+ }
+ }
+}
+
+
+/*
+ * The function mainCRTStartup is the entry point for all console programs.
+ */
+int
+mainCRTStartup ()
+{
+ int nRet;
+
+ /*
+ * I have been told that this is the correct thing to do. You
+ * have to uncomment the prototype of SetUnhandledExceptionFilter
+ * in the GNU Win32 API headers for this to work. The type it
+ * expects is a pointer to a function of the same type as
+ * UnhandledExceptionFilter, which is prototyped just above
+ * (see Functions.h).
+ */
+ SetUnhandledExceptionFilter (NULL);
+ /*
+ * Initialize errno.
+ */
+ errno = 0;
+
+ /*
+ * Initialize floating point unit.
+ */
+ _fpreset (); /* Supplied by the runtime library. */
+
+ /*
+ * Set up __argc, __argv and _environ.
+ */
+ _mingw32_init_mainargs();
+
+
+ /*
+ * Sets the default file mode for stdin, stdout and stderr, as well
+ * as files later opened by the user, to _CRT_fmode.
+ * NOTE: DLLs don't do this because that would be rude!
+ */
+ _mingw32_init_fmode();
+
+ /*
+ * Call the main function. If the user does not supply one
+ * the one in the 'libmingw32.a' library will be linked in, and
+ * that one calls WinMain. See main.c in the 'lib' dir
+ * for more details.
+ */
+
+ nRet = cmdmain(_argc, _argv, environ);
+
+ /*
+ * Perform exit processing for the C library. This means
+ * flushing output and calling 'atexit' registered functions.
+ */
+ _cexit();
+
+ ExitProcess (nRet);
+
+ return 0;
+}
+
+/*
+ * For now the GUI startup function is the same as the console one.
+ * This simply gets rid of the annoying warning about not being able
+ * to find WinMainCRTStartup when linking GUI applications.
+ */
+int
+WinMainCRTStartup ()
+{
+ return mainCRTStartup();
+}
+
+/* With the EGCS build from Mumit Khan (or apparently b19 from Cygnus) this
+ * is no longer necessary. */
+#if 0
+#ifdef __GNUC__
+/*
+ * This section terminates the list of imports under GCC. If you do not
+ * include this then you will have problems when linking with DLLs.
+ *
+ */
+asm (".section .idata$3\n" ".long 0,0,0,0,0,0,0,0");
+#endif
+#endif
+
+
--- /dev/null
+/*
+ * dllcrt1.c
+ *
+ * Initialization code for DLLs.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ * DLL support adapted from Gunther Ebert <gunther.ebert@ixos-leipzig.de>
+ *
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAMED. This includes but is not limited to warrenties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:43 $
+ *
+ */
+
+#include <stdio.h>
+#include <io.h>
+#include <process.h>
+#include <windows.h>
+
+/* See note in crt0.c */
+#include "init.c"
+
+/* Unlike normal crt0, I don't initialize the FPU, because the process
+ * should have done that already. I also don't set the file handle modes,
+ * because that would be rude. */
+
+#ifdef __GNUC__
+extern void __main();
+extern void __do_global_dtors();
+#endif
+
+extern BOOL WINAPI DllMain(HANDLE, DWORD, LPVOID);
+
+BOOL WINAPI
+DllMainCRTStartup (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
+{
+ BOOL bRet;
+
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ _mingw32_init_mainargs();
+
+#ifdef __GNUC__
+ /* From libgcc.a, calls global class constructors. */
+ __main();
+#endif
+ }
+
+ /*
+ * Call the user-supplied DllMain subroutine
+ * NOTE: DllMain is optional, so libmingw32.a includes a stub
+ * which will be used if the user does not supply one.
+ */
+ bRet = DllMain(hDll, dwReason, lpReserved);
+
+#ifdef __GNUC__
+ if (dwReason == DLL_PROCESS_DETACH)
+ {
+ /* From libgcc.a, calls global class destructors. */
+ __do_global_dtors();
+ }
+#endif
+
+ return bRet;
+}
+
+/*
+ * For the moment a dummy atexit. Atexit causes problems in DLLs, especially
+ * if they are dynamically loaded. For now atexit inside a DLL does nothing.
+ * NOTE: We need this even if the DLL author never calls atexit because
+ * the global constructor function __do_global_ctors called from __main
+ * will attempt to register __do_global_dtors using atexit.
+ * Thanks to Andrey A. Smirnov for pointing this one out.
+ */
+int
+atexit (void (*pfn)())
+{
+ return 0;
+}
+
+/* With the EGCS snapshot from Mumit Khan (or b19 from Cygnus I hear) this
+ * is no longer necessary. */
+#if 0
+#ifdef __GNUC__
+/*
+ * This section terminates the list of imports under GCC. If you do not
+ * include this then you will have problems when linking with DLLs.
+ */
+asm (".section .idata$3\n" ".long 0,0,0,0,0,0,0,0");
+#endif
+#endif
--- /dev/null
+/*
+ * dllmain.c
+ *
+ * A stub DllMain function which will be called by DLLs which do not
+ * have a user supplied DllMain.
+ *
+ * Contributors:
+ * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAMED. This includes but is not limited to warrenties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:43 $
+ *
+ */
+
+#include <windows.h>
+
+BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
+{
+ return TRUE;
+}
+
--- /dev/null
+/*
+ * gccmain.c
+ *
+ * A separate version of __main, __do_global_ctors and __do_global_dtors for
+ * Mingw32 for use with Cygwin32 b19. Hopefully this object file will only
+ * be linked if the libgcc.a doesn't include __main, __do_global_dtors and
+ * __do_global_ctors.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ * Code supplied by Stan Cox <scox@cygnus.com>
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:43 $
+ *
+ */
+
+/* Needed for the atexit prototype. */
+#include <stdlib.h>
+
+typedef void (*func_ptr) (void);
+extern func_ptr __CTOR_LIST__[];
+extern func_ptr __DTOR_LIST__[];
+
+void
+__do_global_dtors (void)
+{
+ static func_ptr *p = __DTOR_LIST__ + 1;
+
+ /*
+ * Call each destructor in the destructor list until a null pointer
+ * is encountered.
+ */
+ while (*p)
+ {
+ (*(p)) ();
+ p++;
+ }
+}
+
+void
+__do_global_ctors (void)
+{
+ unsigned long nptrs = (unsigned long) __CTOR_LIST__[0];
+ unsigned i;
+
+ /*
+ * If the first entry in the constructor list is -1 then the list
+ * is terminated with a null entry. Otherwise the first entry was
+ * the number of pointers in the list.
+ */
+ if (nptrs == -1)
+ {
+ for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++)
+ ;
+ }
+
+ /*
+ * Go through the list backwards calling constructors.
+ */
+ for (i = nptrs; i >= 1; i--)
+ {
+ __CTOR_LIST__[i] ();
+ }
+
+ /*
+ * Register the destructors for processing on exit.
+ */
+ atexit (__do_global_dtors);
+}
+
+static int initialized = 0;
+
+void
+__main (void)
+{
+ if (! initialized)
+ {
+ initialized = 1;
+ __do_global_ctors ();
+ }
+}
+
--- /dev/null
+/*
+ * init.c
+ *
+ * Code to initialize standard file handles and command line arguments.
+ * This file is #included in both crt1.c and dllcrt1.c.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAMED. This includes but is not limited to warrenties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:43 $
+ *
+ */
+
+/*
+ * Access to a standard 'main'-like argument count and list. Also included
+ * is a table of environment variables.
+ */
+int _argc = 0;
+char** _argv = 0;
+
+/* NOTE: Thanks to Pedro A. Aranda Gutiirrez <paag@tid.es> for pointing
+ * this out to me. GetMainArgs (used below) takes a fourth argument
+ * which is an int that controls the globbing of the command line. If
+ * _CRT_glob is non-zero the command line will be globbed (e.g. *.*
+ * expanded to be all files in the startup directory). In the mingw32
+ * library a _CRT_glob variable is defined as being -1, enabling
+ * this command line globbing by default. To turn it off and do all
+ * command line processing yourself (and possibly escape bogons in
+ * MS's globbing code) include a line in one of your source modules
+ * defining _CRT_glob and setting it to zero, like this:
+ * int _CRT_glob = 0;
+ */
+extern int _CRT_glob;
+
+#ifdef __MSVCRT__
+extern void __getmainargs(int *, char***, char***, int);
+#else
+extern void __GetMainArgs(int *, char***, char***, int);
+#endif
+
+/*
+ * Initialize the _argc, _argv and environ variables.
+ */
+static void
+_mingw32_init_mainargs ()
+{
+ /* The environ variable is provided directly in stdlib.h through
+ * a dll function call. */
+ char** dummy_environ;
+
+ /*
+ * Microsoft's runtime provides a function for doing just that.
+ */
+#ifdef __MSVCRT__
+ (void) __getmainargs(&_argc, &_argv, &dummy_environ, _CRT_glob);
+#else
+ /* CRTDLL version */
+ (void) __GetMainArgs(&_argc, &_argv, &dummy_environ, _CRT_glob);
+#endif
+}
+
--- /dev/null
+/*
+ * main.c
+ *
+ * Extra startup code for applications which do not have a main function
+ * of their own (but do have a WinMain). Generally these are GUI
+ * applications, but they don't *have* to be.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAMED. This includes but is not limited to warrenties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:43 $
+ *
+ */
+
+#include <stdlib.h>
+#include <process.h>
+#include <windows.h>
+
+#define ISSPACE(a) (a == ' ' || a == '\t')
+
+extern int PASCAL WinMain (HANDLE hInst, HANDLE hPrevInst, LPSTR szCmdLine,
+ int nShow);
+
+int
+main (int argc, char* argv[], char* environ[])
+{
+ char* szCmd;
+ STARTUPINFO startinfo;
+ int nRet;
+
+ /* Get the command line passed to the process. */
+ szCmd = GetCommandLineA();
+ GetStartupInfoA(&startinfo);
+
+ /* Strip off the name of the application and any leading
+ * whitespace. */
+ if (szCmd)
+ {
+ while(ISSPACE(*szCmd))
+ {
+ szCmd++;
+ }
+
+ /* On my system I always get the app name enclosed
+ * in quotes... */
+ if (*szCmd == '\"')
+ {
+ do
+ {
+ szCmd++;
+ }
+ while (*szCmd != '\"' && *szCmd != '\0');
+
+ if (*szCmd == '\"')
+ {
+ szCmd++;
+ }
+ }
+ else
+ {
+ /* If no quotes then assume first token is program
+ * name. */
+ while (!ISSPACE(*szCmd) && *szCmd != '\0')
+ {
+ szCmd++;
+ }
+ }
+
+ while (ISSPACE(*szCmd))
+ {
+ szCmd++;
+ }
+ }
+
+ nRet = WinMain (GetModuleHandle(NULL), NULL, szCmd,
+ (startinfo.dwFlags & STARTF_USESHOWWINDOW) ?
+ startinfo.wShowWindow : SW_SHOWDEFAULT);
+
+ return nRet;
+}
+
--- /dev/null
+#include <windows.h>
+
+
+void sleep(unsigned long timeout)
+{
+ Sleep((timeout)?timeout:1);
+}
\ No newline at end of file
--- /dev/null
+void _global_unwind2( PEXCEPTION_FRAME frame )
+{
+ RtlUnwind( frame, 0, NULL, 0 );
+}
+
+
+void _local_unwind2( PEXCEPTION_FRAME endframe, DWORD nr )
+{
+ TRACE(crtdll,"(%p,%ld)\n",endframe,nr);
+}
\ No newline at end of file
--- /dev/null
+#include <process.h>
+#include <windows.h>
+
+int _cwait( int *termstat, int procHandle, int action )
+{
+ DWORD RetVal;
+ RetVal = WaitForSingleObject((HANDLE)procHandle, INFINITE);
+ if (RetVal == WAIT_FAILED || RetVal == WAIT_ABANDONED) {
+ //errno = ECHILD;
+ return -1;
+ }
+ if ( RetVal == WAIT_OBJECT_0 ) {
+ GetExitCodeProcess((HANDLE)procHandle, termstat);
+ return procHandle;
+ }
+
+
+ return -1;
+ // WAIT_TIMEOUT
+}
\ No newline at end of file
--- /dev/null
+#include <process.h>
+#include <windows.h>
+
+int system(const char *command)
+{
+ char CmdLine[MAX_PATH];
+ char *comspec = getenv("COMSPEC");
+ if ( comspec == NULL )
+ comspec = "cmd.exe";
+ strcpy(CmdLine,comspec);
+ strcat(CmdLine," /C ");
+ if ( !WinExec(CmdLine,SW_SHOWNORMAL) < 31 )
+ return -1;
+
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+#include <process.h>
+
+extern char *const *_environ;
+
+int execl(const char *path, const char *argv0, ...)
+{
+ return spawnve(P_OVERLAY, path, (char *const*)&argv0, _environ);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+
+#include <process.h>
+
+#define scan_ptr() \
+ const char **ptr; \
+ union { const char **ccpp; const char *ccp; } u; \
+ for (ptr = &argv0; *ptr; ptr++); \
+ u.ccp = *++ptr; \
+ ptr = u.ccpp;
+
+int execle(const char *path, const char *argv0, ... /*, const char **envp */)
+{
+ scan_ptr();
+ return spawnve(P_OVERLAY, path, (char *const *)&argv0, (char *const *)ptr);
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+#include <process.h>
+
+
+extern char * const *_environ;
+
+int execlp(const char *path, const char *argv0, ...)
+{
+ return spawnvpe(P_OVERLAY, path, (char * const *)&argv0, _environ);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+#include <process.h>
+
+
+#define scan_ptr() \
+ const char **ptr; \
+ union { const char **ccpp; const char *ccp; } u; \
+ for (ptr = &argv0; *ptr; ptr++); \
+ u.ccp = *++ptr; \
+ ptr = u.ccpp;
+
+int execlpe(const char *path, const char *argv0, ... /*, const char **envp */)
+{
+ scan_ptr();
+ return spawnvpe(P_OVERLAY, path, (char * const *)&argv0, (char * const *)ptr);
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+//#include <unistd.h>
+#include <process.h>
+
+extern char * const *_environ;
+
+int execv(const char *path, const char * const *argv)
+{
+ return spawnve(P_OVERLAY, path, argv, _environ);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+//#include <unistd.h>
+#include <process.h>
+
+int execve(const char *path,const char * const argv[], char * const envp[])
+{
+ return spawnve(P_OVERLAY, path, argv, envp);
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+//#include <unistd.h>
+#include <process.h>
+
+extern char *const *_environ;
+
+int execvp(const char *path,const char * const argv[])
+{
+ return spawnvpe(P_OVERLAY, path, argv, _environ);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+
+#include <process.h>
+
+int execvpe(const char *path,const char * const argv[],const char * const envp[])
+{
+ return spawnvpe(P_OVERLAY, path, argv, envp);
+}
+
+
+int _execvpe(const char *path,const char * const argv[],const char * const envp[])
+{
+ return spawnvpe(P_OVERLAY, path, argv, envp);
+}
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+#include <process.h>
+
+extern char **_environ;
+
+int spawnl(int mode, const char *path, const char *argv0, ...)
+{
+ return spawnve(mode, path, (char * const *)&argv0, _environ);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+#include <process.h>
+
+#define scan_ptr() \
+ const char **ptr; \
+ union { const char **ccpp; const char *ccp; } u; \
+ for (ptr = &argv0; *ptr; ptr++); \
+ u.ccp = *++ptr; \
+ ptr = u.ccpp;
+
+int spawnle(int mode, const char *path, const char *argv0, ... /*, const char **envp */)
+{
+ scan_ptr();
+ return spawnve(mode, path, (char * const *)&argv0, (char * const *)ptr);
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+#include <process.h>
+
+extern char **_environ;
+
+int spawnlp(int mode, const char *path, const char *argv0, ...)
+{
+ return spawnvpe(mode, path, (char * const *)&argv0, (char * const *)_environ);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+#include <process.h>
+#define scan_ptr() \
+ const char **ptr; \
+ union { const char **ccpp; const char *ccp; } u; \
+ for (ptr = &argv0; *ptr; ptr++); \
+ u.ccp = *++ptr; \
+ ptr = u.ccpp;
+
+int spawnlpe(int mode, const char *path, const char *argv0, ... /*, const char **envp */)
+{
+ scan_ptr();
+ return spawnvpe(mode, path, (char * const *)&argv0, (char * const *)ptr);
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+#include <process.h>
+
+extern char **_environ;
+
+int spawnv(int mode, const char *path,const char *const argv[])
+{
+ return spawnve(mode, path, (char * const *)argv, _environ);
+}
--- /dev/null
+#include <process.h>
+#include <string.h>
+#include <windows.h>
+#include <stdio.h>
+
+int _p_overlay = 2;
+
+int spawnve(int mode, const char *path,const char *const argv[],const char *const envp[])
+{
+
+ char ApplicationName[MAX_PATH];
+ char CommandLine[1024];
+ PROCESS_INFORMATION ProcessInformation;
+ STARTUPINFO StartupInfo;
+
+ int i = 0;
+ CommandLine[0] = 0;
+ while(argv[i] != NULL ) {
+ strcat(CommandLine,argv[i]);
+ strcat(CommandLine," ");
+ i++;
+ }
+ strcpy(ApplicationName,argv[0]);
+
+ fflush(stdout); /* just in case */
+ StartupInfo.cb = sizeof(STARTUPINFO);
+ StartupInfo.lpReserved= NULL;
+ StartupInfo.dwFlags = 0;
+
+
+// if ( CreateProcessA(ApplicationName,CommandLine,NULL,NULL,TRUE,CREATE_NEW_CONSOLE|NORMAL_PRIORITY_CLASS,NULL,*envp,&StartupInfo,&ProcessInformation) ) {
+// errno = GetLastError();
+// return -1;
+// }
+
+
+ if (mode == P_OVERLAY)
+ exit(i);
+
+// _P_NOWAIT or _P_NOWAITO
+ return ProcessInformation.hProcess;
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+#include <process.h>
+
+extern char **_environ;
+
+int spawnvp(int mode, const char *path,const char *const argv[])
+{
+ return spawnvpe(mode, path, (char * const *)argv, _environ);
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+#include <process.h>
+#include <errno.h>
+
+
+int spawnvpe(int mode, const char *path,const char *const argv[],const char *const envp[])
+{
+
+ char rpath[300];
+ union {const char * const *cpcp; char **cpp; } u;
+ u.cpcp = envp;
+/*
+ if (!__dosexec_find_on_path(path, u.cpp, rpath))
+ {
+ errno = ENOENT;
+ return -1;
+ }
+ else
+*/
+ return spawnve(mode, rpath, argv, envp);
+
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libc/file.h>
+//#include <libc/local.h>
+//#include <libc/stdiohk.h>
+
+FILE * __alloc_file(void);
+
+
+/* A FILE* is considered "free" if its flag is zero. */
+
+#define __FILE_REC_MAX 20
+typedef struct __file_rec {
+ struct __file_rec *next;
+ int count;
+ FILE *files[__FILE_REC_MAX];
+} __file_rec;
+
+extern __file_rec *__file_rec_list;
+
+FILE *__alloc_file(void)
+{
+ __file_rec *fr = __file_rec_list;
+ __file_rec **last_fr = &__file_rec_list;
+ FILE *rv=0;
+ int i;
+
+ /* Try to find an empty slot */
+ while (fr)
+ {
+ last_fr = &(fr->next);
+
+ /* If one of the existing slots is available, return it */
+ for (i=0; i<fr->count; i++)
+ if (fr->files[i]->_flag == 0)
+ return fr->files[i];
+
+ /* If this one is full, go to the next */
+ if (fr->count == __FILE_REC_MAX)
+ fr = fr->next;
+ else
+ /* it isn't full, we can add to it */
+ break;
+ }
+ if (!fr)
+ {
+ /* add another one to the end, make it empty */
+ fr = *last_fr = (__file_rec *)malloc(sizeof(__file_rec));
+ if (fr == 0)
+ return 0;
+ fr->next = 0;
+ fr->count = 0;
+ }
+ /* fr is a pointer to a rec with empty slots in it */
+ rv = fr->files[fr->count] = (FILE *)malloc(sizeof(FILE));
+ if (rv == 0)
+ return 0;
+ memset(rv, 0, sizeof(FILE));
+ fr->count ++;
+ return rv;
+}
+
+
+int _fcloseall( void )
+{
+ __file_rec *fr = __file_rec_list;
+ __file_rec **last_fr = &__file_rec_list;
+
+ int total_closed;
+ int i = 0;
+
+ /* Try to find an empty slot */
+ while (fr)
+ {
+ last_fr = &(fr->next);
+
+ /* If one of the existing slots is available, return it */
+ for (i=0; i<fr->count; i++)
+ if (fr->files[i]->_flag != 0) {
+ fclose(fr->files[i]);
+ total_closed++;
+ }
+
+ /* If this one is full, go to the next */
+ if (fr->count == __FILE_REC_MAX)
+ fr = fr->next;
+ else
+ /* it isn't full, we can add to it */
+ break;
+ }
+ return total_closed;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+
+#undef clearerr
+void
+clearerr(FILE *f)
+{
+ f->_flag &= ~(_IOERR|_IOEOF);
+}
--- /dev/null
+
+
+
+
+/*
+ * linux/lib/vsprintf.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
+/*
+ * Wirzenius wrote this portably, Torvalds fucked it up :-)
+ */
+
+/*
+ * Appropiated for the reactos kernel, March 1998 -- David Welch
+ */
+
+#include <stdarg.h>
+
+//#include <internal/debug.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <string.h>
+
+//#undef isdigit
+
+size_t strnlen( const char *string, size_t count );
+
+
+static int skip_atoi(const char **s)
+{
+ int i=0;
+
+ while (isdigit(**s))
+ i = i*10 + *((*s)++) - '0';
+ return i;
+}
+
+#define ZEROPAD 1 /* pad with zero */
+#define SIGN 2 /* unsigned/signed long */
+#define PLUS 4 /* show plus */
+#define SPACE 8 /* space if plus */
+#define LEFT 16 /* left justified */
+#define SPECIAL 32 /* 0x */
+#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
+
+
+static int __res;
+
+int do_div(int *n,int base) {
+
+__res = ((unsigned long) *n) % (unsigned) base;
+*n = ((unsigned long) *n) / (unsigned) base;
+return __res;
+}
+
+static char * number(FILE * f, long num, int base, int size, int precision
+ ,int type)
+{
+ char c,sign,tmp[66];
+ const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+ int i;
+
+ if (type & LARGE)
+ digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ if (type & LEFT)
+ type &= ~ZEROPAD;
+ if (base < 2 || base > 36)
+ return 0;
+ c = (type & ZEROPAD) ? '0' : ' ';
+ sign = 0;
+ if (type & SIGN) {
+ if (num < 0) {
+ sign = '-';
+ num = -num;
+ size--;
+ } else if (type & PLUS) {
+ sign = '+';
+ size--;
+ } else if (type & SPACE) {
+ sign = ' ';
+ size--;
+ }
+ }
+ if (type & SPECIAL) {
+ if (base == 16)
+ size -= 2;
+ else if (base == 8)
+ size--;
+ }
+ i = 0;
+ if (num == 0)
+ tmp[i++]='0';
+ else while (num != 0)
+ tmp[i++] = digits[do_div(&num,base)];
+ if (i > precision)
+ precision = i;
+ size -= precision;
+ if (!(type&(ZEROPAD+LEFT)))
+ while(size-->0)
+ putc( ' ',f);
+ if (sign)
+ putc( sign,f);
+ if (type & SPECIAL)
+ if (base==8)
+ putc( '0',f);
+ else if (base==16) {
+ putc( '0', f);
+ putc( digits[33],f);
+ }
+ if (!(type & LEFT))
+ while (size-- > 0)
+ putc( c,f);
+ while (i < precision--)
+ putc( '0', f);
+ while (i-- > 0)
+ putc( tmp[i],f);
+ while (size-- > 0)
+ putc( ' ', f);
+ __res = 0;
+ return 0;
+}
+
+int _doprnt(const char *fmt, va_list args, FILE *f)
+{
+ int len;
+ unsigned long num;
+ int i, base;
+
+ const char *s;
+ const short int* sw;
+
+ int flags; /* flags to number() */
+
+ int field_width; /* width of output field */
+ int precision; /* min. # of digits for integers; max
+ number of chars for from string */
+ int qualifier; /* 'h', 'l', or 'L' for integer fields */
+
+ for (; *fmt ; ++fmt) {
+ if (*fmt != '%') {
+ putc(*fmt,f);
+ continue;
+ }
+
+ /* process flags */
+ flags = 0;
+ repeat:
+ ++fmt; /* this also skips first '%' */
+ switch (*fmt) {
+ case '-': flags |= LEFT; goto repeat;
+ case '+': flags |= PLUS; goto repeat;
+ case ' ': flags |= SPACE; goto repeat;
+ case '#': flags |= SPECIAL; goto repeat;
+ case '0': flags |= ZEROPAD; goto repeat;
+ }
+
+ /* get field width */
+ field_width = -1;
+ if (isdigit(*fmt))
+ field_width = skip_atoi(&fmt);
+ else if (*fmt == '*') {
+ ++fmt;
+ /* it's the next argument */
+ field_width = va_arg(args, int);
+ if (field_width < 0) {
+ field_width = -field_width;
+ flags |= LEFT;
+ }
+ }
+
+ /* get the precision */
+ precision = -1;
+ if (*fmt == '.') {
+ ++fmt;
+ if (isdigit(*fmt))
+ precision = skip_atoi(&fmt);
+ else if (*fmt == '*') {
+ ++fmt;
+ /* it's the next argument */
+ precision = va_arg(args, int);
+ }
+ if (precision < 0)
+ precision = 0;
+ }
+
+ /* get the conversion qualifier */
+ qualifier = -1;
+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
+ qualifier = *fmt;
+ ++fmt;
+ }
+
+ /* default base */
+ base = 10;
+
+ switch (*fmt) {
+ case 'c':
+ if (!(flags & LEFT))
+ while (--field_width > 0)
+ putc(' ',f);
+ putc((unsigned char) va_arg(args, int),f);
+ while (--field_width > 0)
+ putc( ' ',f);
+ continue;
+
+ case 'w':
+ sw = va_arg(args,short int *);
+// DPRINT("L %x\n",sw);
+ if (sw==NULL)
+ {
+// CHECKPOINT;
+ s = "<NULL>";
+ while ((*s)!=0)
+ {
+ putc( *s++,f);
+ }
+// CHECKPOINT;
+// DbgPrint("str %x\n",str);
+ }
+ else
+ {
+ while ((*sw)!=0)
+ {
+ putc( (char)(*sw++),f);
+ }
+ }
+// CHECKPOINT;
+ continue;
+
+ case 's':
+ s = va_arg(args, char *);
+ if (!s)
+ s = "<NULL>";
+
+ len = strnlen(s, precision);
+
+ if (!(flags & LEFT))
+ while (len < field_width--)
+ putc( ' ', f);
+ for (i = 0; i < len; ++i)
+ putc( *s++,f);
+ while (len < field_width--)
+ putc( ' ', f);
+ continue;
+
+ case 'p':
+ if (field_width == -1) {
+ field_width = 2*sizeof(void *);
+ flags |= ZEROPAD;
+ }
+ number(f,
+ (unsigned long) va_arg(args, void *), 16,
+ field_width, precision, flags);
+ continue;
+
+
+ case 'n':
+ if (qualifier == 'l') {
+ long * ip = va_arg(args, long *);
+ //*ip = (str - buf);
+ } else {
+ int * ip = va_arg(args, int *);
+ //*ip = (str - buf);
+ }
+ continue;
+
+ /* integer number formats - set up the flags and "break" */
+ case 'o':
+ base = 8;
+ break;
+
+ case 'b':
+ base = 2;
+ break;
+
+ case 'X':
+ flags |= LARGE;
+ case 'x':
+ base = 16;
+ break;
+
+ case 'd':
+ case 'i':
+ flags |= SIGN;
+ case 'u':
+ break;
+
+ default:
+ if (*fmt != '%')
+ putc( '%', f);
+ if (*fmt)
+ putc( *fmt, f);
+ else
+ --fmt;
+ continue;
+ }
+ if (qualifier == 'l')
+ num = va_arg(args, unsigned long);
+ else if (qualifier == 'h')
+ if (flags & SIGN)
+ num = va_arg(args, short);
+ else
+ num = va_arg(args, unsigned short);
+ else if (flags & SIGN)
+ num = va_arg(args, int);
+ else
+ num = va_arg(args, unsigned int);
+ number(f, num, base, field_width, precision, flags);
+ }
+ //putc('\0',f);
+ return 0;
+}
+
+
+
--- /dev/null
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <libc/file.h>
+
+long double
+_atold(const char *ascii);
+
+
+// dubious variable
+int _fltused = 0;
+
+int
+_doscan_low(FILE *iop, int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *),
+ const char *fmt, void **argp);
+
+//#include <libc/local.h>
+
+#define SPC 01
+#define STP 02
+
+#define SHORT 0
+#define REGULAR 1
+#define LONG 2
+#define LONGDOUBLE 4
+#define INT 0
+#define FLOAT 1
+
+
+
+static int _innum(int **ptr, int type, int len, int size, FILE *iop,
+ int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *),
+ int *eofptr);
+static int _instr(char *ptr, int type, int len, FILE *iop,
+ int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *),
+ int *eofptr);
+static const char *_getccl(const unsigned char *s);
+
+static char _sctab[256] = {
+ 0,0,0,0,0,0,0,0,
+ 0,SPC,SPC,SPC,SPC,SPC,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ SPC,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+};
+
+static int nchars = 0;
+
+int
+_doscan(FILE *iop, const char *fmt, void **argp)
+{
+ return(_doscan_low(iop, fgetc, ungetc, fmt, argp));
+}
+
+int
+_doscan_low(FILE *iop, int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *),
+ const char *fmt, void **argp)
+{
+ register int ch;
+ int nmatch, len, ch1;
+ int **ptr, fileended, size;
+
+ nchars = 0;
+ nmatch = 0;
+ fileended = 0;
+ for (;;) switch (ch = *fmt++) {
+ case '\0':
+ return (nmatch);
+ case '%':
+ if ((ch = *fmt++) == '%')
+ goto def;
+ ptr = 0;
+ if (ch != '*')
+ ptr = (int **)argp++;
+ else
+ ch = *fmt++;
+ len = 0;
+ size = REGULAR;
+ while (isdigit(ch)) {
+ len = len*10 + ch - '0';
+ ch = *fmt++;
+ }
+ if (len == 0)
+ len = 30000;
+
+ if (ch=='l')
+ {
+ size = LONG;
+ ch = *fmt++;
+ if (ch=='l')
+ {
+ size = LONGDOUBLE; /* for long long 'll' format */
+ ch = *fmt++;
+ }
+ }
+ else if (ch=='h') {
+ size = SHORT;
+ ch = *fmt++;
+ } else if (ch=='L') {
+ size = LONGDOUBLE;
+ ch = *fmt++;
+ } else if (ch=='[')
+ fmt = _getccl((const unsigned char *)fmt);
+ if (isupper(ch)) {
+ /* ch = tolower(ch);
+ gcc gives warning: ANSI C forbids braced
+ groups within expressions */
+ ch += 'a' - 'A';
+ if (size==LONG)
+ size = LONGDOUBLE;
+ else if (size != LONGDOUBLE)
+ size = LONG;
+ }
+ if (ch == '\0')
+ return(-1);
+
+ if (ch == 'n')
+ {
+ if (!ptr)
+ break;
+ if (size==LONG)
+ **(long**)ptr = nchars;
+ else if (size==SHORT)
+ **(short**)ptr = nchars;
+ else if (size==LONGDOUBLE)
+ **(long**)ptr = nchars;
+ else
+ **(int**)ptr = nchars;
+ break;
+ }
+
+ if (_innum(ptr, ch, len, size, iop, scan_getc, scan_ungetc,
+ &fileended))
+ {
+ if (ptr)
+ nmatch++;
+ }
+ else
+ {
+ if (fileended && nmatch==0)
+ return(-1);
+ return(nmatch);
+ }
+ break;
+ case ' ':
+ case '\n':
+ case '\t':
+ case '\r':
+ case '\f':
+ case '\v':
+ while (((nchars++, ch1 = scan_getc(iop))!=EOF) && (_sctab[ch1] & SPC))
+ ;
+ if (ch1 != EOF)
+ {
+ scan_ungetc(ch1, iop);
+ }
+ nchars--;
+ break;
+
+ default:
+ def:
+ ch1 = scan_getc(iop);
+ if (ch1 != EOF) nchars++;
+ if (ch1 != ch) {
+ if (ch1==EOF)
+ return(nmatch? nmatch: -1);
+ scan_ungetc(ch1, iop);
+ nchars--;
+ return(nmatch);
+ }
+ }
+}
+
+static int
+_innum(int **ptr, int type, int len, int size, FILE *iop,
+ int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *), int *eofptr)
+{
+ register char *np;
+ char numbuf[64];
+ register int c, base;
+ int expseen, scale, negflg, c1, ndigit;
+ long lcval;
+ int cpos;
+
+ if (type=='c' || type=='s' || type=='[')
+ return(_instr(ptr? *(char **)ptr: (char *)NULL, type, len,
+ iop, scan_getc, scan_ungetc, eofptr));
+ lcval = 0;
+ ndigit = 0;
+ scale = INT;
+ if (type=='e'||type=='f'||type=='g')
+ scale = FLOAT;
+ base = 10;
+ if (type=='o')
+ base = 8;
+ else if (type=='x')
+ base = 16;
+ np = numbuf;
+ expseen = 0;
+ negflg = 0;
+ while (((nchars++, c = scan_getc(iop)) != EOF) && (_sctab[c] & SPC))
+ ;
+ if (c == EOF) nchars--;
+ if (c=='-') {
+ negflg++;
+ *np++ = c;
+ c = scan_getc(iop);
+ nchars++;
+ len--;
+ } else if (c=='+') {
+ len--;
+ c = scan_getc(iop);
+ nchars++;
+ }
+ cpos = 0;
+ for ( ; --len>=0; *np++ = c, c = scan_getc(iop), nchars++) {
+ cpos++;
+ if (c == '0' && cpos == 1 && type == 'i')
+ base = 8;
+ if ((c == 'x' || c == 'X') && (type == 'i' || type == 'x')
+ && cpos == 2 && lcval == 0)
+ {
+ base = 16;
+ continue;
+ }
+ if (isdigit(c)
+ || (base==16 && (('a'<=c && c<='f') || ('A'<=c && c<='F')))) {
+ ndigit++;
+ if (base==8)
+ lcval <<=3;
+ else if (base==10)
+ lcval = ((lcval<<2) + lcval)<<1;
+ else
+ lcval <<= 4;
+ c1 = c;
+ if (isdigit(c))
+ c -= '0';
+ else if ('a'<=c && c<='f')
+ c -= 'a'-10;
+ else
+ c -= 'A'-10;
+ lcval += c;
+ c = c1;
+ continue;
+ } else if (c=='.') {
+ if (base!=10 || scale==INT)
+ break;
+ ndigit++;
+ continue;
+ } else if ((c=='e'||c=='E') && expseen==0) {
+ if (base!=10 || scale==INT || ndigit==0)
+ break;
+ expseen++;
+ *np++ = c;
+ c = scan_getc(iop);
+ nchars++;
+ if (c!='+'&&c!='-'&&('0'>c||c>'9'))
+ break;
+ } else
+ break;
+ }
+ if (negflg)
+ lcval = -lcval;
+ if (c != EOF) {
+ scan_ungetc(c, iop);
+ *eofptr = 0;
+ } else
+ *eofptr = 1;
+ nchars--;
+ if (np==numbuf || (negflg && np==numbuf+1) ) /* gene dykes*/
+ return(0);
+ if (ptr==NULL)
+ return(1);
+ *np++ = 0;
+ switch((scale<<4) | size) {
+
+ case (FLOAT<<4) | SHORT:
+ case (FLOAT<<4) | REGULAR:
+ **(float **)ptr = (float)atof(numbuf);
+ break;
+
+ case (FLOAT<<4) | LONG:
+ **(double **)ptr = atof(numbuf);
+ break;
+
+ case (FLOAT<<4) | LONGDOUBLE:
+ **(long double **)ptr = _atold(numbuf);
+ break;
+
+ case (INT<<4) | SHORT:
+ **(short **)ptr = (short)lcval;
+ break;
+
+ case (INT<<4) | REGULAR:
+ **(int **)ptr = (int)lcval;
+ break;
+
+ case (INT<<4) | LONG:
+ **(long **)ptr = lcval;
+ break;
+
+ case (INT<<4) | LONGDOUBLE:
+ **(long **)ptr = lcval;
+ break;
+ }
+ return(1);
+}
+
+static int
+_instr(char *ptr, int type, int len, FILE *iop,
+ int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *), int *eofptr)
+{
+ register int ch;
+ register char *optr;
+ int ignstp;
+
+ *eofptr = 0;
+ optr = ptr;
+ if (type=='c' && len==30000)
+ len = 1;
+ ignstp = 0;
+ if (type=='s')
+ ignstp = SPC;
+ while ((nchars++, ch = scan_getc(iop)) != EOF && _sctab[ch] & ignstp)
+ ;
+ ignstp = SPC;
+ if (type=='c')
+ ignstp = 0;
+ else if (type=='[')
+ ignstp = STP;
+ while (ch!=EOF && (_sctab[ch]&ignstp)==0) {
+ if (ptr)
+ *ptr++ = ch;
+ if (--len <= 0)
+ break;
+ ch = scan_getc(iop);
+ nchars++;
+ }
+ if (ch != EOF) {
+ if (len > 0)
+ {
+ scan_ungetc(ch, iop);
+ nchars--;
+ }
+ *eofptr = 0;
+ } else
+ {
+ nchars--;
+ *eofptr = 1;
+ }
+ if (!ptr)
+ return(1);
+ if (ptr!=optr) {
+ if (type!='c')
+ *ptr++ = '\0';
+ return(1);
+ }
+ return(0);
+}
+
+static const char *
+_getccl(const unsigned char *s)
+{
+ register int c, t;
+
+ t = 0;
+ if (*s == '^') {
+ t++;
+ s++;
+ }
+ for (c = 0; c < (sizeof _sctab / sizeof _sctab[0]); c++)
+ if (t)
+ _sctab[c] &= ~STP;
+ else
+ _sctab[c] |= STP;
+ if ((c = *s) == ']' || c == '-') { /* first char is special */
+ if (t)
+ _sctab[c] |= STP;
+ else
+ _sctab[c] &= ~STP;
+ s++;
+ }
+ while ((c = *s++) != ']') {
+ if (c==0)
+ return((const char *)--s);
+ else if (c == '-' && *s != ']' && s[-2] < *s) {
+ for (c = s[-2] + 1; c < *s; c++)
+ if (t)
+ _sctab[c] |= STP;
+ else
+ _sctab[c] &= ~STP;
+ } else if (t)
+ _sctab[c] |= STP;
+ else
+ _sctab[c] &= ~STP;
+ }
+ return((const char *)s);
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+#include <stdio.h>
+#include <io.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+//#include <unistd.h>
+#include <libc/file.h>
+
+#ifndef __dj_include_stdio_h_
+#define _name_to_remove _tmpfname
+#endif
+
+int
+fclose(FILE *f)
+{
+ int r;
+
+ r = EOF;
+ if (!f)
+ return r;
+ if (f->_flag & (_IOREAD|_IOWRT|_IORW)
+ && !(f->_flag&_IOSTRG))
+ {
+ r = fflush(f);
+ if (_close(fileno(f)) < 0)
+ r = EOF;
+ if (f->_flag&_IOMYBUF)
+ free(f->_base);
+ }
+ if (f->_flag & _IORMONCL && f->_name_to_remove)
+ {
+ remove(f->_name_to_remove);
+ free(f->_name_to_remove);
+ f->_name_to_remove = 0;
+ }
+ f->_cnt = 0;
+ f->_base = 0;
+ f->_ptr = 0;
+ f->_bufsiz = 0;
+ f->_flag = 0;
+ f->_file = -1;
+ return r;
+}
--- /dev/null
+#include <stdio.h>
+
+FILE *fdopen(int handle, char *mode)
+{
+ FILE *file;
+ int rw;
+
+ if ( handle == 0 )
+ return stdin;
+
+ if ( handle == 1 )
+ return stdout;
+
+ if ( handle == 2 )
+ return stderr;
+
+ if ( handle == 3 )
+ return stdaux;
+
+ if ( handle == 4 )
+ return stdprn;
+
+ file = __alloc_file();
+ if (f == NULL)
+ return NULL;
+ file->_file = handle;
+
+ rw = (mode[1] == '+') || (mode[1] && (mode[2] == '+'));
+
+ if (*mode == 'a')
+ lseek(fd, 0, SEEK_END);
+
+ file->_cnt = 0;
+ file->_file = handle;
+ file->_bufsiz = 0;
+ if (rw)
+ file->_flag = _IORW;
+ else if (*mode == 'r')
+ file->_flag = _IOREAD;
+ else
+ file->_flag = _IOWRT;
+
+ file->_base = f->_ptr = NULL;
+ return file;
+}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+
+#undef feof
+int
+feof(FILE *stream)
+{
+ return stream->_flag & _IOEOF;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+
+#undef ferror
+int
+ferror(FILE *stream)
+{
+ return stream->_flag & _IOERR;
+}
--- /dev/null
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+//#include <unistd.h>
+#include <libc/file.h>
+#include <io.h>
+
+int
+fflush(FILE *f)
+{
+ char *base;
+ int n, rn;
+
+ if (f == NULL)
+ {
+ int e = errno;
+
+ errno = 0;
+ _fwalk((void (*)(FILE *))fflush);
+ if (errno)
+ return EOF;
+ errno = e;
+ return 0;
+ }
+
+ f->_flag &= ~_IOUNGETC;
+ if ((f->_flag&(_IONBF|_IOWRT))==_IOWRT
+ && (base = f->_base) != NULL
+ && (rn = n = f->_ptr - base) > 0)
+ {
+ f->_ptr = base;
+ f->_cnt = (f->_flag&(_IOLBF|_IONBF)) ? 0 : f->_bufsiz;
+ do {
+ n = _write(fileno(f), base, rn);
+ if (n <= 0) {
+ f->_flag |= _IOERR;
+ return EOF;
+ }
+ rn -= n;
+ base += n;
+ } while (rn > 0);
+ }
+ if (f->_flag & _IORW)
+ {
+ f->_cnt = 0;
+ f->_flag &= ~(_IOWRT|_IOREAD);
+ f->_ptr = f->_base;
+ }
+ return 0;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+
+int
+fgetc(FILE *f)
+{
+ return getc(f);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <errno.h>
+
+int
+fgetpos(FILE *stream, fpos_t *pos)
+{
+ if (stream && pos)
+ {
+ *pos = (fpos_t)ftell(stream);
+ return 0;
+ }
+ errno = EFAULT;
+ return 1;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+
+char *
+fgets(char *s, int n, FILE *f)
+{
+ int c=0;
+ char *cs;
+
+ cs = s;
+ while (--n>0 && (c = getc(f)) != EOF)
+ {
+ *cs++ = c;
+ if (c == '\n')
+ break;
+ }
+ if (c == EOF && cs == s)
+ return NULL;
+ *cs++ = '\0';
+ return s;
+}
--- /dev/null
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+//#include <unistd.h>
+#include <string.h>
+//#include <go32.h>
+#include <libc/file.h>
+//#include <libc/stdiohk.h>
+#include <io.h>
+
+/* Note: We set _fillsize to 512, and use that for reading instead of
+ _bufsize, for performance reasons. We double _fillsize each time
+ we read here, and reset it to 512 each time we call fseek. That
+ way, we don't waste time reading data we won't use, or doing lots
+ of small reads we could optimize. If we do lots of seeking, we'll
+ end up maintaining small read sizes, but if we don't seek, we'll
+ eventually read blocks as large as the transfer buffer. */
+
+int
+_filbuf(FILE *f)
+{
+ int size, fillsize;
+ char c;
+
+ if (f->_flag & _IORW)
+ f->_flag |= _IOREAD;
+
+ if ((f->_flag&_IOREAD) == 0)
+ return EOF;
+ if (f->_flag&(_IOSTRG|_IOEOF))
+ return EOF;
+ f->_flag &= ~_IOUNGETC;
+
+ if (f->_base==NULL && (f->_flag&_IONBF)==0) {
+// size = _go32_info_block.size_of_transfer_buffer;
+ size = 512;
+ if ((f->_base = malloc(size)) == NULL)
+ {
+ f->_flag |= _IONBF;
+ f->_flag &= ~(_IOFBF|_IOLBF);
+ }
+ else
+ {
+ f->_flag |= _IOMYBUF;
+ f->_bufsiz = size;
+// f->_fillsize = 512;
+ }
+ }
+
+ if (f->_flag&_IONBF)
+ f->_base = &c;
+
+ if (f == stdin) {
+ if (stdout->_flag&_IOLBF)
+ fflush(stdout);
+ if (stderr->_flag&_IOLBF)
+ fflush(stderr);
+ }
+
+ /* don't read too much! */
+ //if (f->_fillsize > f->_bufsiz)
+ // f->_fillsize = f->_bufsiz;
+
+ /* This next bit makes it so that the cumulative amount read always
+ aligns with file cluster boundaries; i.e. 512, then 2048
+ (512+1536), then 4096 (2048+2048) etc. */
+ //fillsize = f->_fillsize;
+ fillsize = f->_bufsiz;
+ if (fillsize == 1024 && f->_bufsiz >= 1536)
+ fillsize = 1536;
+
+ f->_cnt = _read(fileno(f), f->_base,
+ f->_flag & _IONBF ? 1 : fillsize);
+
+ /* Read more next time, if we don't seek */
+// if (f->_fillsize < f->_bufsiz)
+// f->_fillsize *= 2;
+
+ if(__is_text_file(f) && f->_cnt>0)
+ {
+ /* truncate text file at Ctrl-Z */
+ char *cz=memchr(f->_base, 0x1A, f->_cnt);
+ if(cz)
+ {
+ int newcnt = cz - f->_base;
+ lseek(fileno(f), -(f->_cnt - newcnt), SEEK_CUR);
+ f->_cnt = newcnt;
+ }
+ }
+ f->_ptr = f->_base;
+ if (f->_flag & _IONBF)
+ f->_base = NULL;
+ if (--f->_cnt < 0) {
+ if (f->_cnt == -1) {
+ f->_flag |= _IOEOF;
+ if (f->_flag & _IORW)
+ f->_flag &= ~_IOREAD;
+ } else
+ f->_flag |= _IOERR;
+ f->_cnt = 0;
+ return EOF;
+ }
+ return *f->_ptr++ & 0377;
+}
+
+
--- /dev/null
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+//#include <unistd.h>
+//#include <go32.h>
+#include <libc/file.h>
+#include <io.h>
+
+int
+_flsbuf(int c, FILE *f)
+{
+ char *base;
+ int n, rn;
+ char c1;
+ int size;
+
+ if (f->_flag & _IORW)
+ {
+ f->_flag |= _IOWRT;
+ f->_flag &= ~(_IOEOF|_IOREAD);
+ }
+
+ if ((f->_flag&_IOWRT)==0)
+ return EOF;
+
+ /* if the buffer is not yet allocated, allocate it */
+ if ((base = f->_base) == NULL && (f->_flag & _IONBF) == 0)
+ {
+// size = _go32_info_block.size_of_transfer_buffer;
+ size = 512;
+ if ((f->_base = base = malloc (size)) == NULL)
+ {
+ f->_flag |= _IONBF;
+ f->_flag &= ~(_IOFBF|_IOLBF);
+ }
+ else
+ {
+ f->_flag |= _IOMYBUF;
+ f->_cnt = f->_bufsiz = size;
+ f->_ptr = base;
+ rn = 0;
+ if (f == stdout && isatty (fileno (stdout)))
+ f->_flag |= _IOLBF;
+ }
+ }
+
+ if (f->_flag & _IOLBF)
+ {
+ /* in line-buffering mode we get here on each character */
+ *f->_ptr++ = c;
+ rn = f->_ptr - base;
+ if (c == '\n' || rn >= f->_bufsiz)
+ {
+ /* time for real flush */
+ f->_ptr = base;
+ f->_cnt = 0;
+ }
+ else
+ {
+ /* we got here because _cnt is wrong, so fix it */
+ /* Negative _cnt causes all output functions
+ to call _flsbuf for each character, thus realizing line-buffering */
+ f->_cnt = -rn;
+ return c;
+ }
+ }
+ else if (f->_flag & _IONBF)
+ {
+ c1 = c;
+ rn = 1;
+ base = &c1;
+ f->_cnt = 0;
+ }
+ else /* _IOFBF */
+ {
+ rn = f->_ptr - base;
+ f->_ptr = base;
+ f->_cnt = f->_bufsiz;
+ }
+ while (rn > 0)
+ {
+ n = _write(fileno(f), base, rn);
+ if (n <= 0)
+ {
+ f->_flag |= _IOERR;
+ return EOF;
+ }
+ rn -= n;
+ base += n;
+ }
+ if ((f->_flag&(_IOLBF|_IONBF)) == 0)
+ {
+ f->_cnt--;
+ *f->_ptr++ = c;
+ }
+ return c;
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
+//#include <unistd.h>
+#include <libc/file.h>
+//#include <libc/local.h>
+//#include <libc/dosio.h>
+
+FILE * __alloc_file(void);
+
+extern int _fmode;
+
+FILE *
+fopen(const char *file, const char *mode)
+{
+ FILE *f;
+ int fd, rw, oflags = 0;
+ char tbchar;
+
+ if (file == 0)
+ return 0;
+ if (mode == 0)
+ return 0;
+
+ f = __alloc_file();
+ if (f == NULL)
+ return NULL;
+
+ rw = (mode[1] == '+') || (mode[1] && (mode[2] == '+'));
+
+ switch (*mode)
+ {
+ case 'a':
+ oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY);
+ break;
+ case 'r':
+ oflags = rw ? O_RDWR : O_RDONLY;
+ break;
+ case 'w':
+ oflags = O_TRUNC | O_CREAT | (rw ? O_RDWR : O_WRONLY);
+ break;
+ default:
+ return (NULL);
+ }
+ if (mode[1] == '+')
+ tbchar = mode[2];
+ else
+ tbchar = mode[1];
+ if (tbchar == 't')
+ oflags |= O_TEXT;
+ else if (tbchar == 'b')
+ oflags |= O_BINARY;
+ else
+ oflags |= (_fmode & (O_TEXT|O_BINARY));
+
+ fd = _open(file, oflags, 0);
+ if (fd < 0)
+ return NULL;
+
+ if (*mode == 'a')
+ lseek(fd, 0, SEEK_END);
+
+ f->_cnt = 0;
+ f->_file = fd;
+ f->_bufsiz = 0;
+ if (rw)
+ f->_flag = _IORW;
+ else if (*mode == 'r')
+ f->_flag = _IOREAD;
+ else
+ f->_flag = _IOWRT;
+
+ f->_base = f->_ptr = NULL;
+ return f;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+
+int
+fprintf(register FILE *iop, const char *fmt, ...)
+{
+ int len;
+ char localbuf[BUFSIZ];
+
+ if (iop->_flag & _IONBF)
+ {
+ iop->_flag &= ~_IONBF;
+ iop->_ptr = iop->_base = localbuf;
+ iop->_bufsiz = BUFSIZ;
+ len = _doprnt(fmt, (&fmt)+1, iop);
+ fflush(iop);
+ iop->_flag |= _IONBF;
+ iop->_base = NULL;
+ iop->_bufsiz = 0;
+ iop->_cnt = 0;
+ }
+ else
+ len = _doprnt(fmt, (&fmt)+1, iop);
+ return ferror(iop) ? EOF : len;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+
+int
+fputc(int c, FILE *fp)
+{
+ return putc(c, fp);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+#include <windows.h>
+
+int
+fputs(const char *s, FILE *f)
+{
+ /*
+ int r = 0;
+ int c;
+ int unbuffered;
+ char localbuf[BUFSIZ];
+
+ unbuffered = f->_flag & _IONBF;
+ if (unbuffered)
+ {
+ f->_flag &= ~_IONBF;
+ f->_ptr = f->_base = localbuf;
+ f->_bufsiz = BUFSIZ;
+ }
+
+ while ((c = *s++))
+ r = putc(c, f);
+
+ if (unbuffered)
+ {
+ fflush(f);
+ f->_flag |= _IONBF;
+ f->_base = NULL;
+ f->_bufsiz = 0;
+ f->_cnt = 0;
+ }
+
+ return(r);
+ */
+ int r = 0;
+ if ( !WriteFile(filehnd(f->_file),s,strlen(s),&r,NULL) )
+ return -1;
+
+ return r;
+}
--- /dev/null
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libc/file.h>
+
+#define _fillsize _bufsiz
+
+size_t
+fread(void *vptr, size_t size, size_t count, FILE *iop)
+{
+ char *ptr = (char *)vptr;
+ int s;
+ int c;
+
+ /* grow if we know we're asking for a lot, even if it's in the
+ buffer, since we'll probably read chunks this size for a while */
+ while (size*count > iop->_fillsize
+ && iop->_fillsize < iop->_bufsiz)
+ {
+ if (iop->_fillsize < 512)
+ iop->_fillsize = 512;
+ iop->_fillsize *= 2;
+ }
+
+ s = size * count;
+ if(!__is_text_file(iop))
+ {
+ while (s > 0) {
+ if (iop->_cnt < s) {
+ if (iop->_cnt > 0) {
+ memcpy(ptr, iop->_ptr, iop->_cnt);
+ ptr += iop->_cnt;
+ s -= iop->_cnt;
+ }
+ /*
+ * filbuf clobbers _cnt & _ptr,
+ * so don't waste time setting them.
+ */
+ if ((c = _filbuf(iop)) == EOF)
+ break;
+ *ptr++ = c;
+ s--;
+ }
+ if (iop->_cnt >= s) {
+ memcpy(ptr, iop->_ptr, s);
+ iop->_ptr += s;
+ iop->_cnt -= s;
+ return count;
+ }
+ }
+ }
+ else
+ {
+ while (s > 0) {
+ if (iop->_cnt < s) {
+ while (iop->_cnt > 0) {
+ if ((c = *iop->_ptr++) != '\r')
+ {
+ *ptr++ = c;
+ s--;
+ }
+ iop->_cnt--;
+ }
+ if ((c = _filbuf(iop)) == EOF)
+ break;
+ if (c != '\r')
+ {
+ *ptr++ = c;
+ s--;
+ }
+ }
+ if (iop->_cnt >= s) {
+ while (s > 0 && iop->_cnt > 0) {
+ if ((c = *iop->_ptr++) != '\r')
+ {
+ *ptr++ = c;
+ s--;
+ }
+ iop->_cnt--;
+ }
+ }
+ } /* end while */
+ }
+ return size != 0 ? count - ((s + size - 1) / size) : 0;
+}
+
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+//#include <unistd.h>
+#include <libc/file.h>
+#include <io.h>
+
+extern int _fmode;
+
+FILE *
+freopen(const char *file, const char *mode, FILE *f)
+{
+ int fd, rw, oflags=0;
+ char tbchar;
+
+ if (file == 0 || mode == 0 || f == 0)
+ return 0;
+
+ rw = (mode[1] == '+');
+
+ fclose(f);
+
+ switch (*mode) {
+ case 'a':
+ oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY);
+ break;
+ case 'r':
+ oflags = rw ? O_RDWR : O_RDONLY;
+ break;
+ case 'w':
+ oflags = O_TRUNC | O_CREAT | (rw ? O_RDWR : O_WRONLY);
+ break;
+ default:
+ return NULL;
+ }
+ if (mode[1] == '+')
+ tbchar = mode[2];
+ else
+ tbchar = mode[1];
+ if (tbchar == 't')
+ oflags |= O_TEXT;
+ else if (tbchar == 'b')
+ oflags |= O_BINARY;
+ else
+ oflags |= (_fmode & (O_TEXT|O_BINARY));
+
+ fd = _open(file, oflags, 0666);
+ if (fd < 0)
+ return NULL;
+
+ if (*mode == 'a')
+ lseek(fd, 0, SEEK_END);
+
+ f->_cnt = 0;
+ f->_file = fd;
+ f->_bufsiz = 0;
+ if (rw)
+ f->_flag = _IORW;
+ else if (*mode == 'r')
+ f->_flag = _IOREAD;
+ else
+ f->_flag = _IOWRT;
+
+ f->_base = f->_ptr = NULL;
+ return f;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+//#include <libc/local.h>
+
+static __file_rec __initial_file_rec = {
+ 0,
+ 5,
+{ stdin, stdout, stderr, stdprn, stdaux }
+};
+
+__file_rec *__file_rec_list = &__initial_file_rec;
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <stdarg.h>
+#include <libc/file.h>
+
+int
+fscanf(FILE *f, const char *fmt, ...)
+{
+ int r;
+ va_list a=0;
+ va_start(a, fmt);
+ r = _doscan(f, fmt, a);
+ va_end(a);
+ return r;
+}
--- /dev/null
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+#include <stdio.h>
+#include <libc/file.h>
+#include <fcntl.h>
+#include <io.h>
+
+#define _fillsize _bufsiz
+
+int
+fseek(FILE *f, long offset, int ptrname)
+{
+ long p = -1; /* can't happen? */
+
+ /* See comment in filbuf.c */
+ f->_fillsize = 512;
+
+ f->_flag &= ~_IOEOF;
+ if (f->_flag & _IOREAD)
+ {
+ if (f->_base && !(f->_flag & _IONBF))
+ {
+ p = ftell(f);
+ if (ptrname == SEEK_CUR)
+ {
+ offset += p;
+ ptrname = SEEK_SET;
+ }
+ /* check if the target position is in the buffer and
+ optimize seek by moving inside the buffer */
+ if (ptrname == SEEK_SET && (f->_flag & (_IOUNGETC|_IORW)) == 0
+ && p-offset <= f->_ptr-f->_base && offset-p <= f->_cnt)
+ {
+ f->_ptr+=offset-p;
+ f->_cnt+=p-offset;
+ return 0;
+ }
+ }
+
+ if (f->_flag & _IORW)
+ f->_flag &= ~_IOREAD;
+
+ p = lseek(fileno(f), offset, ptrname);
+ f->_cnt = 0;
+ f->_ptr = f->_base;
+ f->_flag &= ~_IOUNGETC;
+ }
+ else if (f->_flag & (_IOWRT|_IORW))
+ {
+ p = fflush(f);
+ return lseek(fileno(f), offset, ptrname) == -1 || p == EOF ?
+ -1 : 0;
+ }
+ return p==-1 ? -1 : 0;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <errno.h>
+
+int
+fsetpos(FILE *stream, const fpos_t *pos)
+{
+ if (stream && pos)
+ {
+ fseek(stream, (long)(*pos), SEEK_SET);
+ return 0;
+ }
+ errno = EFAULT;
+ return 1;
+}
--- /dev/null
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+#include <stdio.h>
+//#include <unistd.h>
+#include <libc/file.h>
+#include <fcntl.h>
+#include <io.h>
+
+
+long
+ftell(FILE *f)
+{
+ long tres;
+ int adjust=0;
+
+ if (f->_cnt < 0)
+ f->_cnt = 0;
+ if (f->_flag&_IOREAD)
+ {
+ adjust = - f->_cnt;
+ }
+ else if (f->_flag&(_IOWRT|_IORW))
+ {
+ if (f->_flag&_IOWRT && f->_base && (f->_flag&_IONBF)==0)
+ adjust = f->_ptr - f->_base;
+ }
+ else
+ return -1;
+ tres = lseek(fileno(f), 0L, 1);
+ if (tres<0)
+ return tres;
+ tres += adjust;
+ return tres;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+//#include <libc/local.h>
+
+#define __FILE_REC_MAX 20
+typedef struct __file_rec {
+ struct __file_rec *next;
+ int count;
+ FILE *files[__FILE_REC_MAX];
+} __file_rec;
+
+__file_rec *__file_rec_list;
+
+void
+_fwalk(void (*func)(FILE *))
+{
+ __file_rec *fr;
+ int i;
+
+ for (fr=__file_rec_list; fr; fr=fr->next)
+ for (i=0; i<fr->count; i++)
+ if (fr->files[i]->_flag)
+ func(fr->files[i]);
+}
--- /dev/null
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libc/file.h>
+
+size_t
+fwrite(const void *vptr, size_t size, size_t count, FILE *f)
+{
+ const char *ptr = (const char *)vptr;
+ register int s;
+
+ s = size * count;
+ if(!__is_text_file(f))
+ {
+ if (f->_flag & _IOLBF)
+ while (s > 0) {
+ if (--f->_cnt > -f->_bufsiz && *(const char *)ptr != '\n')
+ *f->_ptr++ = *(const char *)ptr++;
+ else if (_flsbuf(*(const char *)ptr++, f) == EOF)
+ break;
+ s--;
+ }
+ else while (s > 0) {
+ if (f->_cnt < s) {
+ if (f->_cnt > 0) {
+ memcpy(f->_ptr, ptr, f->_cnt);
+ ptr += f->_cnt;
+ f->_ptr += f->_cnt;
+ s -= f->_cnt;
+ }
+ if (_flsbuf(*(const unsigned char *)ptr++, f) == EOF)
+ break;
+ s--;
+ }
+ if (f->_cnt >= s) {
+ memcpy(f->_ptr, ptr, s);
+ f->_ptr += s;
+ f->_cnt -= s;
+ return count;
+ }
+ }
+ }
+ else
+ {
+ if (f->_flag & _IOLBF)
+ {
+ while (s > 0) {
+ if (*ptr=='\n')
+ {
+ if (--f->_cnt > -f->_bufsiz)
+ *f->_ptr++ = '\r';
+ else
+ if (_flsbuf('\r', f) == EOF)
+ break;
+ }
+ if (--f->_cnt > -f->_bufsiz && *ptr != '\n')
+ *f->_ptr++ = *ptr++;
+ else if (_flsbuf(*(const unsigned char *)ptr++, f) == EOF)
+ break;
+ s--;
+ }
+ }
+ else
+ {
+ while (s > 0)
+ {
+ if (*ptr == '\n')
+ {
+ if(--f->_cnt >= 0)
+ *f->_ptr++ = '\r';
+ else
+ if (_flsbuf('\r', f) == EOF)
+ break;
+ }
+ if (--f->_cnt >= 0)
+ *f->_ptr++ = *ptr++;
+ else
+ if (_flsbuf(*(const unsigned char *)ptr++, f) == EOF)
+ break;
+ s--;
+ }
+ }
+ }
+ return size != 0 ? count - ((s + size - 1) / size) : 0;
+}
+
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <windows.h>
+#include <libc/file.h>
+
+#undef getc
+int getc(FILE *f)
+{
+ int c;
+ DWORD NumberOfBytesRead;
+ if ( !ReadFile(filehnd(f->_file),&c, 1, &NumberOfBytesRead, NULL) )
+ return -1;
+ if ( NumberOfBytesRead == 0 )
+ return -1;
+ return c;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+
+#undef getchar
+int
+getchar(void)
+{
+ return getc(stdin);
+}
--- /dev/null
+#include <windows.h>
+#include <stdlib.h>
+
+void *malloc(size_t size);
+
+
+
+char *getenv(const char *name)
+{
+ char *buffer;
+ buffer = (char *)malloc(MAX_PATH);
+ buffer[0] = 0;
+ if ( GetEnvironmentVariableA(name,buffer,MAX_PATH) == 0 )
+ return NULL;
+ return buffer;
+}
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+
+char *
+gets(char *s)
+{
+ int c;
+ char *cs;
+
+ cs = s;
+ while ((c = getchar()) != '\n' && c != EOF)
+ *cs++ = c;
+ if (c == EOF && cs==s)
+ return NULL;
+ *cs++ = '\0';
+ return s;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+
+int
+getw(FILE *f)
+{
+ int i;
+ char *p;
+ int w;
+
+ p = (char *)&w;
+ for (i=sizeof(int); --i>=0;)
+ *p++ = getc(f);
+ if (feof(f))
+ return EOF;
+ return w;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+
+
+void
+perror(const char *s)
+{
+
+ fprintf(stderr, "%s: %s\n", s, _strerror(NULL));
+}
--- /dev/null
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+#include <internal/debug.h>
+int
+printf(const char *fmt, ...)
+{
+ int len;
+
+ len = _doprnt(fmt, (&fmt)+1, stdout);
+
+ /* People were confused when printf() didn't flush stdout,
+ so we'll do it to reduce confusion */
+ if (stdout->_flag & _IOLBF)
+ fflush(stdout);
+
+ return ferror(stdout) ? EOF : len;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <windows.h>
+#include <libc/file.h>
+
+#undef putc
+int putc(int c, FILE *fp)
+{
+
+ int r;
+
+// if(c =='\n' && __is_text_file(fp))
+// putc('\r',fp);
+
+
+ if ( ((fp->_flag) & _IOSTRG) == _IOSTRG) {
+ if(fp->_cnt>0)
+ {
+ fp->_cnt--;
+ return((unsigned char)(*(fp->_ptr++)=(unsigned char)c));
+ }
+ return(_flsbuf(c,fp));
+ }
+ if ( !WriteFile(filehnd(fp->_file),&c,1,&r,NULL) )
+ return -1;
+ return r;
+
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/conio/getch.c
+ * PURPOSE: Writes a character to stdout
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+#include <stdio.h>
+
+#undef putc
+#undef putchar
+int
+putchar(int c)
+{
+ int r = putc(c, stdout);
+ if (stdout->_flag & _IOLBF)
+ fflush(stdout);
+ return r;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <windows.h>
+
+#undef putchar
+int
+puts(const char *s)
+{
+ /*
+ int c;
+
+ while ((c = *s++))
+ putchar(c);
+ return putchar('\n');
+ */
+ int r = 0;
+ if ( !WriteFile(filehnd(stdout->_file),s,strlen(s),&r,NULL) )
+ return -1;
+
+ return putchar('\n');;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+
+int
+putw(int w, FILE *f)
+{
+ char *p;
+ int i;
+
+ p = (char *)&w;
+ for (i=sizeof(int); --i>=0;)
+ putc(*p++, f);
+ return ferror(f);
+}
--- /dev/null
+#include <windows.h>
+
+int remove(const char *fn)
+{
+ if (!DeleteFileA(fn))
+ return -1;
+ return 0;
+}
+
\ No newline at end of file
--- /dev/null
+#include <windows.h>
+#include <stdio.h>
+#include <io.h>
+
+int rename(const char *old, const char *new)
+{
+ return _rename(old,new);
+}
+
+int _rename(const char *old, const char *new)
+{
+ if ( !MoveFile(old,new) )
+ return -1;
+
+ return 0;
+}
+
+
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+#include <stdio.h>
+#include <io.h>
+#include <libc/file.h>
+
+
+void rewind(FILE *f)
+{
+ fflush(f);
+ lseek(fileno(f), 0L, SEEK_SET);
+ f->_cnt = 0;
+ f->_ptr = f->_base;
+ f->_flag &= ~(_IOERR|_IOEOF);
+ if (f->_flag & _IORW)
+ f->_flag &= ~(_IOREAD|_IOWRT);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <stdarg.h>
+#include <libc/file.h>
+
+int
+scanf(const char *fmt, ...)
+{
+ int r;
+ va_list a=0;
+ va_start(a, fmt);
+ r = _doscan(stdin, fmt, a);
+ va_end(a);
+ return r;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <stdlib.h>
+#include <libc/file.h>
+
+void
+setbuf(FILE *f, char *buf)
+{
+ if (buf)
+ setvbuf(f, buf, _IOFBF, BUFSIZ);
+ else
+ setvbuf(f, 0, _IONBF, BUFSIZ);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void setbuffer(FILE *f, void *buf, int size)
+{
+ if (buf)
+ setvbuf(f, buf, _IOFBF, size);
+ else
+ setvbuf(f, 0, _IONBF, 0);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+
+void setlinebuf(FILE *f)
+{
+ setvbuf(f, 0, _IOLBF, BUFSIZ);
+}
--- /dev/null
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <stdlib.h>
+#include <io.h>
+#include <libc/file.h>
+
+#define _fillsize _bufsiz
+
+int setvbuf(FILE *f, char *buf, int type, size_t len)
+{
+ int mine=0;
+ if (!f)
+ return -1;
+ fflush(f);
+ switch (type)
+ {
+ case _IOFBF:
+ case _IOLBF:
+ if (len <= 0)
+ return -1;
+ if (buf == 0)
+ {
+ buf = (char *)malloc(len);
+ if (buf == 0)
+ return -1;
+ mine = 1;
+ }
+ f->_fillsize = len; /* make it read in `len'-byte chunks */
+ /* FALLTHROUGH */
+ case _IONBF:
+ if (f->_base != NULL && f->_flag & _IOMYBUF)
+ free(f->_base);
+ f->_cnt = 0;
+
+ f->_flag &= ~(_IONBF|_IOFBF|_IOLBF|_IOUNGETC);
+ f->_flag |= type;
+ if (type != _IONBF)
+ {
+ if (mine)
+ f->_flag |= _IOMYBUF;
+ f->_ptr = f->_base = buf;
+ f->_bufsiz = len;
+ }
+ else
+ {
+ f->_base = 0;
+ f->_bufsiz = 0;
+ }
+ return 0;
+ default:
+ return -1;
+ }
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <limits.h>
+#include <libc/file.h>
+
+
+int
+sprintf(char *str, const char *fmt, ...)
+{
+ FILE _strbuf;
+ int len;
+
+ _strbuf._flag = _IOWRT|_IOSTRG;
+ _strbuf._ptr = str;
+ _strbuf._cnt = INT_MAX;
+ len = _doprnt(fmt, &(fmt)+1, &_strbuf);
+ *_strbuf._ptr = 0;
+ return len;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <stdarg.h>
+#include <libc/file.h>
+//#include <libc/unconst.h>
+
+int
+sscanf(const char *str, const char *fmt, ...)
+{
+ int r;
+ va_list a=0;
+ FILE _strbuf;
+
+ va_start(a, fmt);
+
+ _strbuf._flag = _IOREAD|_IOSTRG;
+ _strbuf._ptr = (char *)str;
+ _strbuf._base = (char *)str;
+ _strbuf._cnt = 0;
+ while (*str++)
+ _strbuf._cnt++;
+ _strbuf._bufsiz = _strbuf._cnt;
+ r = _doscan(&_strbuf, fmt, a);
+ va_end(a);
+ return r;
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+//#include <libc/stdiohk.h>
+
+
+FILE _iob[] =
+{
+ // stdin
+{
+ NULL, 0, NULL,
+ _IOREAD | _IOLBF ,
+ 0, 0,0, NULL
+},
+ // stdout
+{
+ NULL, 0, NULL,
+ _IOWRT | _IOFBF |_IOSTRG,
+ 1,0,0, NULL
+},
+ // stderr
+{
+ NULL, 0, NULL,
+ _IOWRT | _IONBF,
+ 2,0,0, NULL
+},
+ // stdaux
+{
+ NULL, 0, NULL,
+ _IORW | _IONBF,
+ 3,0,0, NULL
+},
+ // stdprn
+{
+ NULL, 0, NULL,
+ _IOWRT | _IONBF,
+ 4, 0,0,NULL
+}
+};
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+//#include <libc/local.h>
+
+static void fcloseall_helper(FILE *f)
+{
+ fflush(f);
+ if (fileno(f) > 2)
+ fclose(f);
+}
+
+void __stdio_cleanup_proc(void);
+void __stdio_cleanup_proc(void)
+{
+ _fwalk(fcloseall_helper);
+}
+
+void (*__stdio_cleanup_hook)(void) = __stdio_cleanup_proc;
--- /dev/null
+#include <stdio.h>
+#include <windows.h>
+
+
+
+char *_tempnam(const char *dir,const char *prefix )
+{
+ char *TempFileName;
+ TempFileName = malloc(MAX_PATH);
+ GetTempFileName(
+ dir,
+ prefix,
+ 98,
+ TempFileName
+ );
+ return TempFileName;
+}
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+//#include <libc/stubs.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+//#include <unistd.h>
+#include <io.h>
+#include <libc/file.h>
+#include <share.h>
+
+#ifndef __dj_include_stdio_h_
+#define _name_to_remove _tmpfname
+#endif
+
+FILE * __alloc_file(void);
+
+FILE *
+tmpfile(void)
+{
+ int temp_fd;
+ FILE *f;
+ char *temp_name = tmpnam(0);
+ char *n_t_r = (char *)malloc(L_tmpnam);
+
+ if (!n_t_r)
+ return 0;
+
+ /* We could have a race condition, whereby another program
+ (in another virtual machine, or if the temporary file is
+ in a directory which is shared via a network) opens the
+ file returned by `tmpnam' between the call above and the
+ moment when we actually open the file below. This loop
+ retries the call to `tmpnam' until we actually succeed
+ to create the file which didn't exist before. */
+ do {
+ errno = 0;
+ temp_fd = _open(temp_name, 0, SH_DENYRW);
+ } while (temp_fd == -1 && errno != ENOENT && (temp_name = tmpnam(0)) != 0);
+
+ if (temp_name == 0)
+ return 0;
+
+ /* This should have been fdopen(temp_fd, "wb+"), but `fdopen'
+ is non-ANSI. So we need to dump some of its guts here. Sigh... */
+ f = __alloc_file();
+ if (f)
+ {
+ f->_file = temp_fd;
+ f->_cnt = 0;
+ f->_bufsiz = 0;
+ f->_flag = _IORMONCL | _IORW;
+ f->_name_to_remove = n_t_r;
+ strcpy(f->_name_to_remove, temp_name);
+ f->_base = f->_ptr = NULL;
+ }
+ else
+ {
+ close(temp_fd);
+ remove(temp_name);
+ free(n_t_r);
+ }
+ return f;
+}
--- /dev/null
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+
+char *
+_tmpnam(char *s);
+
+char *
+tmpnam(char *s)
+{
+ return _tmpnam(s);
+}
+
+
+char *
+_tmpnam(char *s)
+{
+ char PathName[MAX_PATH];
+ static char static_buf[MAX_PATH];
+ GetTempPath(MAX_PATH,PathName);
+ GetTempFileNameA(PathName, "ARI",007,static_buf);
+ strcpy(s,static_buf);
+ return s;
+}
--- /dev/null
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <libc/file.h>
+
+int
+ungetc(int c, FILE *f)
+{
+ if (c == EOF
+ || (f->_flag & (_IOREAD|_IORW)) == 0
+ || f->_ptr == NULL
+ || f->_base == NULL)
+ return EOF;
+
+ if (f->_ptr == f->_base)
+ {
+ if (f->_cnt == 0)
+ f->_ptr++;
+ else
+ return EOF;
+ }
+
+ f->_cnt++;
+ f->_ptr--;
+ if(*f->_ptr != c)
+ {
+ f->_flag |= _IOUNGETC;
+ *f->_ptr = c;
+ }
+
+ return c;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <stdarg.h>
+#include <libc/file.h>
+
+int
+vfprintf(FILE *f, const char *fmt, va_list ap)
+{
+ int len;
+ char localbuf[BUFSIZ];
+
+ if (f->_flag & _IONBF)
+ {
+ f->_flag &= ~_IONBF;
+ f->_ptr = f->_base = localbuf;
+ f->_bufsiz = BUFSIZ;
+ len = _doprnt(fmt, ap, f);
+ (void)fflush(f);
+ f->_flag |= _IONBF;
+ f->_base = NULL;
+ f->_bufsiz = 0;
+ f->_cnt = 0;
+ }
+ else
+ len = _doprnt(fmt, ap, f);
+ return (ferror(f) ? EOF : len);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <stdarg.h>
+#include <libc/file.h>
+
+int
+vprintf(const char *fmt, va_list ap)
+{
+ int len;
+
+ len = _doprnt(fmt, ap, stdout);
+ return (ferror(stdout) ? EOF : len);
+}
-/*
- * linux/lib/vsprintf.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
-/*
- * Wirzenius wrote this portably, Torvalds fucked it up :-)
- */
-
-/*
- * Appropiated for the reactos kernel, March 1998 -- David Welch
- */
-
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
#include <stdarg.h>
+#include <limits.h>
+#include <libc/file.h>
-#include <internal/debug.h>
-#include <internal/ctype.h>
-#include <internal/string.h>
-
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
-{
- unsigned long result = 0,value;
-
- if (!base) {
- base = 10;
- if (*cp == '0') {
- base = 8;
- cp++;
- if ((*cp == 'x') && isxdigit(cp[1])) {
- cp++;
- base = 16;
- }
- }
- }
- while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
- ? toupper(*cp) : *cp)-'A'+10) < base) {
- result = result*base + value;
- cp++;
- }
- if (endp)
- *endp = (char *)cp;
- return result;
-}
-
-/* we use this so that we can do without the ctype library */
-#define is_digit(c) ((c) >= '0' && (c) <= '9')
-
-static int skip_atoi(const char **s)
-{
- int i=0;
-
- while (is_digit(**s))
- i = i*10 + *((*s)++) - '0';
- return i;
-}
-
-#define ZEROPAD 1 /* pad with zero */
-#define SIGN 2 /* unsigned/signed long */
-#define PLUS 4 /* show plus */
-#define SPACE 8 /* space if plus */
-#define LEFT 16 /* left justified */
-#define SPECIAL 32 /* 0x */
-#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
-
-#define do_div(n,base) ({ \
-int __res; \
-__res = ((unsigned long) n) % (unsigned) base; \
-n = ((unsigned long) n) / (unsigned) base; \
-__res; })
-
-static char * number(char * str, long num, int base, int size, int precision
- ,int type)
+int
+vsprintf(char *str, const char *fmt, va_list ap)
{
- char c,sign,tmp[66];
- const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
- int i;
-
- if (type & LARGE)
- digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- if (type & LEFT)
- type &= ~ZEROPAD;
- if (base < 2 || base > 36)
- return 0;
- c = (type & ZEROPAD) ? '0' : ' ';
- sign = 0;
- if (type & SIGN) {
- if (num < 0) {
- sign = '-';
- num = -num;
- size--;
- } else if (type & PLUS) {
- sign = '+';
- size--;
- } else if (type & SPACE) {
- sign = ' ';
- size--;
- }
- }
- if (type & SPECIAL) {
- if (base == 16)
- size -= 2;
- else if (base == 8)
- size--;
- }
- i = 0;
- if (num == 0)
- tmp[i++]='0';
- else while (num != 0)
- tmp[i++] = digits[do_div(num,base)];
- if (i > precision)
- precision = i;
- size -= precision;
- if (!(type&(ZEROPAD+LEFT)))
- while(size-->0)
- *str++ = ' ';
- if (sign)
- *str++ = sign;
- if (type & SPECIAL)
- if (base==8)
- *str++ = '0';
- else if (base==16) {
- *str++ = '0';
- *str++ = digits[33];
- }
- if (!(type & LEFT))
- while (size-- > 0)
- *str++ = c;
- while (i < precision--)
- *str++ = '0';
- while (i-- > 0)
- *str++ = tmp[i];
- while (size-- > 0)
- *str++ = ' ';
- return str;
+ FILE f;
+ int len;
+
+ f._flag = _IOWRT|_IOSTRG;
+ f._ptr = str;
+ f._cnt = INT_MAX;
+ len = _doprnt(fmt, ap, &f);
+ *f._ptr = 0;
+ return len;
}
-
-int vsprintf(char *buf, const char *fmt, va_list args)
-{
- int len;
- unsigned long num;
- int i, base;
- char * str;
- const char *s;
- const short int* sw;
-
- int flags; /* flags to number() */
-
- int field_width; /* width of output field */
- int precision; /* min. # of digits for integers; max
- number of chars for from string */
- int qualifier; /* 'h', 'l', or 'L' for integer fields */
-
- for (str=buf ; *fmt ; ++fmt) {
- if (*fmt != '%') {
- *str++ = *fmt;
- continue;
- }
-
- /* process flags */
- flags = 0;
- repeat:
- ++fmt; /* this also skips first '%' */
- switch (*fmt) {
- case '-': flags |= LEFT; goto repeat;
- case '+': flags |= PLUS; goto repeat;
- case ' ': flags |= SPACE; goto repeat;
- case '#': flags |= SPECIAL; goto repeat;
- case '0': flags |= ZEROPAD; goto repeat;
- }
-
- /* get field width */
- field_width = -1;
- if (is_digit(*fmt))
- field_width = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- field_width = va_arg(args, int);
- if (field_width < 0) {
- field_width = -field_width;
- flags |= LEFT;
- }
- }
-
- /* get the precision */
- precision = -1;
- if (*fmt == '.') {
- ++fmt;
- if (is_digit(*fmt))
- precision = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- precision = va_arg(args, int);
- }
- if (precision < 0)
- precision = 0;
- }
-
- /* get the conversion qualifier */
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
- qualifier = *fmt;
- ++fmt;
- }
-
- /* default base */
- base = 10;
-
- switch (*fmt) {
- case 'c':
- if (!(flags & LEFT))
- while (--field_width > 0)
- *str++ = ' ';
- *str++ = (unsigned char) va_arg(args, int);
- while (--field_width > 0)
- *str++ = ' ';
- continue;
-
- case 'w':
- sw = va_arg(args,short int *);
-// DPRINT("L %x\n",sw);
- if (sw==NULL)
- {
-// CHECKPOINT;
- s = "<NULL>";
- while ((*s)!=0)
- {
- *str++ = *s++;
- }
-// CHECKPOINT;
-// DbgPrint("str %x\n",str);
- }
- else
- {
- while ((*sw)!=0)
- {
- *str++ = (char)(*sw++);
- }
- }
-// CHECKPOINT;
- continue;
-
- case 's':
- s = va_arg(args, char *);
- if (!s)
- s = "<NULL>";
-
- len = strnlen(s, precision);
-
- if (!(flags & LEFT))
- while (len < field_width--)
- *str++ = ' ';
- for (i = 0; i < len; ++i)
- *str++ = *s++;
- while (len < field_width--)
- *str++ = ' ';
- continue;
-
- case 'p':
- if (field_width == -1) {
- field_width = 2*sizeof(void *);
- flags |= ZEROPAD;
- }
- str = number(str,
- (unsigned long) va_arg(args, void *), 16,
- field_width, precision, flags);
- continue;
-
-
- case 'n':
- if (qualifier == 'l') {
- long * ip = va_arg(args, long *);
- *ip = (str - buf);
- } else {
- int * ip = va_arg(args, int *);
- *ip = (str - buf);
- }
- continue;
-
- /* integer number formats - set up the flags and "break" */
- case 'o':
- base = 8;
- break;
-
- case 'b':
- base = 2;
- break;
-
- case 'X':
- flags |= LARGE;
- case 'x':
- base = 16;
- break;
-
- case 'd':
- case 'i':
- flags |= SIGN;
- case 'u':
- break;
-
- default:
- if (*fmt != '%')
- *str++ = '%';
- if (*fmt)
- *str++ = *fmt;
- else
- --fmt;
- continue;
- }
- if (qualifier == 'l')
- num = va_arg(args, unsigned long);
- else if (qualifier == 'h')
- if (flags & SIGN)
- num = va_arg(args, short);
- else
- num = va_arg(args, unsigned short);
- else if (flags & SIGN)
- num = va_arg(args, int);
- else
- num = va_arg(args, unsigned int);
- str = number(str, num, base, field_width, precision, flags);
- }
- *str = '\0';
- return str-buf;
-}
-
-int sprintf(char * buf, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i=vsprintf(buf,fmt,args);
- va_end(args);
- return i;
-}
-
--- /dev/null
+#include <windows.h>
+#include <stdlib.h>
+#include <io.h>
+#include <fcntl.h>
+#include <libc/atexit.h>
+
+void _exit(int _status);
+
+struct __atexit *__atexit_ptr = 0;
+
+void
+exit(int status)
+{
+ //int i;
+ struct __atexit *a = __atexit_ptr;
+ __atexit_ptr = 0; /* to prevent infinite loops */
+ while (a)
+ {
+ (a->__function)();
+ a = a->__next;
+ }
+/*
+ if (__stdio_cleanup_hook)
+ __stdio_cleanup_hook();
+ for (i=0; i<djgpp_last_dtor-djgpp_first_dtor; i++)
+ djgpp_first_dtor[i]();
+*/
+ /* in case the program set it this way */
+ setmode(0, O_TEXT);
+ _exit(status);
+}
+
+
+
+void _exit(int _status)
+{
+ //ExitProcess(_status);
+}
+
+void _cexit( void )
+{
+ // flush
+}
+
+void _c_exit( void )
+{
+ // reset interup vectors
+}
\ No newline at end of file
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <io.h>
+
+static char msg[] = "Abort!\r\n";
+
+void
+abort()
+{
+ _write(stderr->_file, msg, sizeof(msg)-1);
+ _exit(1);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+int
+abs(int j)
+{
+ return j<0 ? -j : j;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+#include <libc/atexit.h>
+
+int
+atexit(void (*a)(void))
+{
+ struct __atexit *ap;
+ if (a == 0)
+ return -1;
+ ap = (struct __atexit *)malloc(sizeof(struct __atexit));
+ if (!ap)
+ return -1;
+ ap->__next = __atexit_ptr;
+ ap->__function = a;
+ __atexit_ptr = ap;
+ return 0;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+double
+atof(const char *ascii)
+{
+ return strtod(ascii, 0);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+int
+atoi(const char *str)
+{
+ return (int)strtol(str, 0, 10);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+long
+atol(const char *str)
+{
+ return strtol(str, 0, 10);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+long double
+_atold(const char *ascii)
+{
+ return _strtold(ascii, 0);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+#include <libc/unconst.h>
+
+void *
+bsearch(const void *key, const void *base0, size_t nelem,
+ size_t size, int (*cmp)(const void *ck, const void *ce))
+{
+ char *base = unconst(base0, char *);
+ int lim, cmpval;
+ void *p;
+
+ for (lim = nelem; lim != 0; lim >>= 1)
+ {
+ p = base + (lim >> 1) * size;
+ cmpval = (*cmp)(key, p);
+ if (cmpval == 0)
+ return p;
+ if (cmpval > 0)
+ { /* key > p: move right */
+ base = (char *)p + size;
+ lim--;
+ } /* else move left */
+ }
+ return 0;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+#include <string.h>
+
+void *
+calloc(size_t size, size_t nelem)
+{
+ void *rv = malloc(size*nelem);
+ if (rv)
+ memset(rv, 0, size*nelem);
+ return rv;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+div_t
+div(int num, int denom)
+{
+ div_t r;
+
+ if (num > 0 && denom < 0) {
+ num = -num;
+ denom = -denom;
+ }
+ r.quot = num / denom;
+ r.rem = num % denom;
+ if (num < 0 && denom > 0)
+ {
+ if (r.rem > 0)
+ {
+ r.quot++;
+ r.rem -= denom;
+ }
+ }
+ return r;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <errno.h>
+
+#undef errno
+int errno;
+int _doserrno;
+
+
+int _errno(void)
+{
+ return errno;
+}
+
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/crtdll/stdlib/fullpath.c
+ * PURPOSE: Gets the fullpathname
+ * PROGRAMER: Boudewijn Dekker
+ * UPDATE HISTORY:
+ * 28/12/98: Created
+ */
+#include <stdlib.h>
+#include <windows.h>
+
+#undef fullpath
+char *fullpath( char *absPath, const char *relPath, size_t maxLength )
+{
+ return _fullpath(absPath,relPath,maxLength );
+}
+
+char *_fullpath( char *absPath, const char *relPath, size_t maxLength )
+{
+
+
+ char *lpFilePart;
+ if ( GetFullPathName(relPath,maxLength,absPath,&lpFilePart) == 0 )
+ return NULL;
+
+ return absPath;
+}
+
+
+
+
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+long
+labs(long j)
+{
+ return j<0 ? -j : j;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+ldiv_t
+ldiv(long num, long denom)
+{
+ ldiv_t r;
+
+ if (num > 0 && denom < 0)
+ {
+ num = -num;
+ denom = -denom;
+ }
+ r.quot = num / denom;
+ r.rem = num % denom;
+ if (num < 0 && denom > 0)
+ {
+ if (r.rem > 0)
+ {
+ r.quot++;
+ r.rem -= denom;
+ }
+ }
+ return r;
+}
--- /dev/null
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+long long
+llabs(long long j)
+{
+ return j<0 ? -j : j;
+}
--- /dev/null
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+lldiv_t
+lldiv(long long num, long long denom)
+{
+ lldiv_t r;
+
+ if (num > 0 && denom < 0)
+ {
+ num = -num;
+ denom = -denom;
+ }
+ r.quot = num / denom;
+ r.rem = num % denom;
+ if (num < 0 && denom > 0)
+ {
+ if (r.rem > 0)
+ {
+ r.quot++;
+ r.rem -= denom;
+ }
+ }
+ return r;
+}
--- /dev/null
+#include <stdlib.h>
+#include <string.h>
+
+void _makepath( char *path, const char *drive, const char *dir, const char *fname, const char *ext )
+{
+ int dir_len;
+ if ( drive != NULL ) {
+ strcat(path,drive);
+ strcat(path,":");
+ }
+
+ if ( dir != NULL ) {
+ strcat(path,dir);
+ if ( *dir != '\\' )
+ strcat(path,"\\");
+ dir_len = strlen(dir);
+ if ( *(dir + dir_len - 1) != '\\' )
+ strcat(path,"\\");
+ }
+ if ( fname != NULL ) {
+ strcat(path,fname);
+ if ( ext != NULL ) {
+ if ( *ext != '.')
+ strcat(path,".");
+ strcat(path,ext);
+ }
+ }
+
+
+}
\ No newline at end of file
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: lib/crtdll/stdlib/malloc.c
- * PURPOSE: stdc memory allocation functions
- * PROGRAMMER: ??
- */
-
-/* INCLUDES ******************************************************************/
-
#include <windows.h>
-#include <types.h>
-
-/* FUNCTIONS *****************************************************************/
+#include <stdlib.h>
+//#include <types.h>
+#include <ddk/ntddk.h>
-void* malloc(size_t size)
+void* malloc(size_t _size)
{
- return(HeapAlloc(GetProcessHeap(), 0, size));
+ return(HeapAlloc(GetProcessHeap(),
+ 0,
+ _size));
}
-void free(void* ptr)
+void free(void* _ptr)
{
- HeapFree(GetProcessHeap(), 0, ptr);
+ HeapFree(GetProcessHeap(),
+ 0,
+ _ptr);
}
-void* calloc(size_t nmemb, size_t size)
+void* calloc(size_t _nmemb, size_t _size)
{
- return(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nmemb*size));
+ return(HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ _nmemb*_size));
}
-void* realloc(void* ptr, size_t size)
+void* realloc(void* _ptr, size_t _size)
{
- return(HeapReAlloc(GetProcessHeap(), 0, ptr, size));
+ ExFreePool(_ptr);
+ return ExAllocatePool(NonPagedPool,_size );
+#if 0
+ return(HeapReAlloc(GetProcessHeap(),
+ 0,
+ _ptr,
+ _size));
+#endif
}
--- /dev/null
+#include <windows.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+int
+putenv(const char *val)
+{
+
+ char buffer[1024];
+ char *epos;
+
+ strcpy(buffer,val);
+
+
+ epos = strchr(buffer, '=');
+ if ( epos == NULL )
+ return -1;
+
+ *epos = 0;
+
+ return SetEnvironmentVariableA(buffer,epos+1);
+}
+
+
+
+
+
+
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+/*-
+ * Copyright (c) 1980, 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * qsort.c:
+ * Our own version of the system qsort routine which is faster by an average
+ * of 25%, with lows and highs of 10% and 50%.
+ * The THRESHold below is the insertion sort threshold, and has been adjusted
+ * for records of size 48 bytes.
+ * The MTHREShold is where we stop finding a better median.
+ */
+
+#define THRESH 4 /* threshold for insertion */
+#define MTHRESH 6 /* threshold for median */
+
+static int (*qcmp)(const void *, const void *); /* the comparison routine */
+static int qsz; /* size of each record */
+static int thresh; /* THRESHold in chars */
+static int mthresh; /* MTHRESHold in chars */
+
+/*
+ * qst:
+ * Do a quicksort
+ * First, find the median element, and put that one in the first place as the
+ * discriminator. (This "median" is just the median of the first, last and
+ * middle elements). (Using this median instead of the first element is a big
+ * win). Then, the usual partitioning/swapping, followed by moving the
+ * discriminator into the right place. Then, figure out the sizes of the two
+ * partions, do the smaller one recursively and the larger one via a repeat of
+ * this code. Stopping when there are less than THRESH elements in a partition
+ * and cleaning up with an insertion sort (in our caller) is a huge win.
+ * All data swaps are done in-line, which is space-losing but time-saving.
+ * (And there are only three places where this is done).
+ */
+
+static void
+qst(char *base, char *max)
+{
+ char c, *i, *j, *jj;
+ int ii;
+ char *mid, *tmp;
+ int lo, hi;
+
+ /*
+ * At the top here, lo is the number of characters of elements in the
+ * current partition. (Which should be max - base).
+ * Find the median of the first, last, and middle element and make
+ * that the middle element. Set j to largest of first and middle.
+ * If max is larger than that guy, then it's that guy, else compare
+ * max with loser of first and take larger. Things are set up to
+ * prefer the middle, then the first in case of ties.
+ */
+ lo = max - base; /* number of elements as chars */
+ do {
+ mid = i = base + qsz * ((lo / qsz) >> 1);
+ if (lo >= mthresh)
+ {
+ j = (qcmp((jj = base), i) > 0 ? jj : i);
+ if (qcmp(j, (tmp = max - qsz)) > 0)
+ {
+ /* switch to first loser */
+ j = (j == jj ? i : jj);
+ if (qcmp(j, tmp) < 0)
+ j = tmp;
+ }
+ if (j != i)
+ {
+ ii = qsz;
+ do {
+ c = *i;
+ *i++ = *j;
+ *j++ = c;
+ } while (--ii);
+ }
+ }
+ /*
+ * Semi-standard quicksort partitioning/swapping
+ */
+ for (i = base, j = max - qsz; ; )
+ {
+ while (i < mid && qcmp(i, mid) <= 0)
+ i += qsz;
+ while (j > mid)
+ {
+ if (qcmp(mid, j) <= 0)
+ {
+ j -= qsz;
+ continue;
+ }
+ tmp = i + qsz; /* value of i after swap */
+ if (i == mid)
+ {
+ /* j <-> mid, new mid is j */
+ mid = jj = j;
+ }
+ else
+ {
+ /* i <-> j */
+ jj = j;
+ j -= qsz;
+ }
+ goto swap;
+ }
+ if (i == mid)
+ {
+ break;
+ }
+ else
+ {
+ /* i <-> mid, new mid is i */
+ jj = mid;
+ tmp = mid = i; /* value of i after swap */
+ j -= qsz;
+ }
+ swap:
+ ii = qsz;
+ do {
+ c = *i;
+ *i++ = *jj;
+ *jj++ = c;
+ } while (--ii);
+ i = tmp;
+ }
+ /*
+ * Look at sizes of the two partitions, do the smaller
+ * one first by recursion, then do the larger one by
+ * making sure lo is its size, base and max are update
+ * correctly, and branching back. But only repeat
+ * (recursively or by branching) if the partition is
+ * of at least size THRESH.
+ */
+ i = (j = mid) + qsz;
+ if ((lo = j - base) <= (hi = max - i))
+ {
+ if (lo >= thresh)
+ qst(base, j);
+ base = i;
+ lo = hi;
+ }
+ else
+ {
+ if (hi >= thresh)
+ qst(i, max);
+ max = j;
+ }
+ } while (lo >= thresh);
+}
+
+/*
+ * qsort:
+ * First, set up some global parameters for qst to share. Then, quicksort
+ * with qst(), and then a cleanup insertion sort ourselves. Sound simple?
+ * It's not...
+ */
+
+void
+qsort(void *base0, size_t n, size_t size, int (*compar)(const void *, const void *))
+{
+ char *base = (char *)base0;
+ char c, *i, *j, *lo, *hi;
+ char *min, *max;
+
+ if (n <= 1)
+ return;
+ qsz = size;
+ qcmp = compar;
+ thresh = qsz * THRESH;
+ mthresh = qsz * MTHRESH;
+ max = base + n * qsz;
+ if (n >= THRESH)
+ {
+ qst(base, max);
+ hi = base + thresh;
+ }
+ else
+ {
+ hi = max;
+ }
+ /*
+ * First put smallest element, which must be in the first THRESH, in
+ * the first position as a sentinel. This is done just by searching
+ * the first THRESH elements (or the first n if n < THRESH), finding
+ * the min, and swapping it into the first position.
+ */
+ for (j = lo = base; (lo += qsz) < hi; )
+ if (qcmp(j, lo) > 0)
+ j = lo;
+ if (j != base)
+ {
+ /* swap j into place */
+ for (i = base, hi = base + qsz; i < hi; )
+ {
+ c = *j;
+ *j++ = *i;
+ *i++ = c;
+ }
+ }
+ /*
+ * With our sentinel in place, we now run the following hyper-fast
+ * insertion sort. For each remaining element, min, from [1] to [n-1],
+ * set hi to the index of the element AFTER which this one goes.
+ * Then, do the standard insertion sort shift on a character at a time
+ * basis for each element in the frob.
+ */
+ for (min = base; (hi = min += qsz) < max; )
+ {
+ while (qcmp(hi -= qsz, min) > 0)
+ /* void */;
+ if ((hi += qsz) != min) {
+ for (lo = min + qsz; --lo >= min; )
+ {
+ c = *lo;
+ for (i = j = lo; (j -= qsz) >= hi; i = j)
+ *i = *j;
+ *i = c;
+ }
+ }
+ }
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+
+static unsigned long long next = 0;
+
+int
+rand(void)
+{
+ next = next * 0x5deece66dLL + 11;
+ return (int)((next >> 16) & RAND_MAX);
+}
+
+void
+srand(unsigned seed)
+{
+ next = seed;
+}
--- /dev/null
+#include <stdlib.h>
+#include <windows.h>
+#include <string.h>
+
+void _searchenv(const char *file,const char *var,char *path )
+{
+ char *env = getenv(var);
+
+ char *x;
+ char *y;
+ char *FilePart;
+ x = strchr(env,'=');
+ if ( x != NULL ) {
+ *x = 0;
+ x++;
+ }
+ y = strchr(env,';');
+ while ( y != NULL ) {
+ *y = 0;
+ if ( SearchPathA(x,file,NULL,MAX_PATH,path,&FilePart) > 0 ) {
+ return;
+ }
+ x = y+1;
+ y = strchr(env,';');
+ }
+ return;
+
+}
\ No newline at end of file
--- /dev/null
+#include <stdlib.h>
+#include <string.h>
+
+void _splitpath( const char *path, char *drive, char *dir, char *fname, char *ext )
+{
+ char *tmp_drive;
+ char *tmp_dir;
+ char *tmp_ext;
+
+ tmp_drive = (char *)strchr(path,':');
+ if ( tmp_drive != (char *)NULL ) {
+ strncpy(drive,tmp_drive-1,1);
+ *(drive+1) = 0;
+ }
+ else {
+ *drive = 0;
+ tmp_drive = (char *)path;
+ }
+
+ tmp_dir = (char *)strrchr(path,'\\');
+ if( tmp_dir != NULL && tmp_dir != tmp_drive + 1 ) {
+ strncpy(dir,tmp_drive+1,tmp_dir - tmp_drive);
+ *(dir + (tmp_dir - tmp_drive)) = 0;
+ }
+ else
+ *dir =0;
+
+ tmp_ext = ( char *)strrchr(path,'.');
+ if ( tmp_ext != NULL ) {
+ strcpy(ext,tmp_ext);
+ }
+ else
+ *ext = 0;
+ if ( tmp_dir != NULL ) {
+ strncpy(fname,tmp_dir+1,tmp_ext - tmp_dir - 1);
+ *(fname + (tmp_ext - tmp_dir -1)) = 0;
+ }
+ else
+ strncpy(fname,path,tmp_ext - path);
+
+}
+
--- /dev/null
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <math.h>
+#include <stdlib.h>
+
+
+double
+strtod(const char *s, char **sret)
+{
+ long double r; /* result */
+ int e; /* exponent */
+ long double d; /* scale */
+ int sign; /* +- 1.0 */
+ int esign;
+ int i;
+ int flags=0;
+
+ r = 0.0;
+ sign = 1;
+ e = 0;
+ esign = 1;
+
+ while ((*s == ' ') || (*s == '\t'))
+ s++;
+
+ if (*s == '+')
+ s++;
+ else if (*s == '-')
+ {
+ sign = -1;
+ s++;
+ }
+
+ while ((*s >= '0') && (*s <= '9'))
+ {
+ flags |= 1;
+ r *= 10.0;
+ r += *s - '0';
+ s++;
+ }
+
+ if (*s == '.')
+ {
+ d = 0.1L;
+ s++;
+ while ((*s >= '0') && (*s <= '9'))
+ {
+ flags |= 2;
+ r += d * (*s - '0');
+ s++;
+ d *= 0.1L;
+ }
+ }
+
+ if (flags == 0)
+ {
+ if (sret)
+ *sret = (char *)s;
+ return 0;
+ }
+
+ if ((*s == 'e') || (*s == 'E'))
+ {
+ s++;
+ if (*s == '+')
+ s++;
+ else if (*s == '-')
+ {
+ s++;
+ esign = -1;
+ }
+ if ((*s < '0') || (*s > '9'))
+ {
+ if (sret)
+ *sret = (char *)s;
+ return r;
+ }
+
+ while ((*s >= '0') && (*s <= '9'))
+ {
+ e *= 10;
+ e += *s - '0';
+ s++;
+ }
+ }
+
+ if (esign < 0)
+ for (i = 1; i <= e; i++)
+ r *= 0.1L;
+ else
+ for (i = 1; i <= e; i++)
+ r *= 10.0;
+
+ if (sret)
+ *sret = (char *)s;
+ return r * sign;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+
+
+long
+strtol(const char *nptr, char **endptr, int base)
+{
+ const char *s = nptr;
+ unsigned long acc;
+ int c;
+ unsigned long cutoff;
+ int neg = 0, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-')
+ {
+ neg = 1;
+ c = *s++;
+ }
+ else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X'))
+ {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for longs is
+ * [-2147483648..2147483647] and the input base is 10,
+ * cutoff will be set to 214748364 and cutlim to either
+ * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ * the number is too big, and we will return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+ cutlim = cutoff % (unsigned long)base;
+ cutoff /= (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++)
+ {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else
+ {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0)
+ {
+ acc = neg ? LONG_MIN : LONG_MAX;
+ errno = ERANGE;
+ }
+ else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = any ? (char *)s - 1 : (char *)nptr;
+ return acc;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+#include <ctype.h>
+//#include <libc/unconst.h>
+
+static double powten[] =
+{
+ 1e1L, 1e2L, 1e4L, 1e8L, 1e16L, 1e32L, 1e64L, 1e128L, 1e256L
+ //1e512L, 1e512L*1e512L, 1e2048L, 1e4096L
+};
+
+double
+_strtold(const char *s, char **sret)
+{
+#if 0
+ double r; /* result */
+ int e, ne; /* exponent */
+ int sign; /* +- 1.0 */
+ int esign;
+ int flags=0;
+ int l2powm1;
+
+ r = 0.0L;
+ sign = 1;
+ e = ne = 0;
+ esign = 1;
+
+ while(*s && isspace(*s))
+ s++;
+
+ if (*s == '+')
+ s++;
+ else if (*s == '-')
+ {
+ sign = -1;
+ s++;
+ }
+
+ while ((*s >= '0') && (*s <= '9'))
+ {
+ flags |= 1;
+ r *= 10.0L;
+ r += *s - '0';
+ s++;
+ }
+
+ if (*s == '.')
+ {
+ s++;
+ while ((*s >= '0') && (*s <= '9'))
+ {
+ flags |= 2;
+ r *= 10.0L;
+ r += *s - '0';
+ s++;
+ ne++;
+ }
+ }
+ if (flags == 0)
+ {
+ if (sret)
+ *sret = (char *)s;
+ return 0.0L;
+ }
+
+ if ((*s == 'e') || (*s == 'E'))
+ {
+ s++;
+ if (*s == '+')
+ s++;
+ else if (*s == '-')
+ {
+ s++;
+ esign = -1;
+ }
+ while ((*s >= '0') && (*s <= '9'))
+ {
+ e *= 10;
+ e += *s - '0';
+ s++;
+ }
+ }
+ if (esign < 0)
+ {
+ esign = -esign;
+ e = -e;
+ }
+ e = e - ne;
+ if (e < -4096)
+ {
+ /* possibly subnormal number, 10^e would overflow */
+ r *= 1.0e-2048L;
+ e += 2048;
+ }
+ if (e < 0)
+ {
+ e = -e;
+ esign = -esign;
+ }
+ if (e >= 8192)
+ e = 8191;
+ if (e)
+ {
+ double d = 1.0L;
+ l2powm1 = 0;
+ while (e)
+ {
+ if (e & 1)
+ d *= powten[l2powm1];
+ e >>= 1;
+ l2powm1++;
+ }
+ if (esign > 0)
+ r *= d;
+ else
+ r /= d;
+ }
+ if (sret)
+ *sret = (char *)s;
+ return r * sign;
+
+#endif
+ return 0;
+}
--- /dev/null
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+//#include <libc/unconst.h>
+
+/* constants used in Solaris */
+#define LLONG_MIN -9223372036854775807L-1L
+#define LLONG_MAX 9223372036854775807L
+#define ULLONG_MAX 18446744073709551615UL
+
+long
+strtoll(const char *nptr, char **endptr, int base)
+{
+ const char *s = nptr;
+ unsigned long acc;
+ int c;
+ unsigned long cutoff;
+ int neg = 0, any, cutlim;
+
+ /*
+ * See strtol for comments as to the logic used.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-')
+ {
+ neg = 1;
+ c = *s++;
+ }
+ else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X'))
+ {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+/* to prevent overflow, we take max-1 and add 1 after division */
+ cutoff = neg ? -(LLONG_MIN+1) : LLONG_MAX-1;
+ cutlim = cutoff % base;
+ cutoff /= base;
+ if (++cutlim == base)
+ {
+ cutlim = 0;
+ cutoff++;
+ }
+ for (acc = 0, any = 0;; c = *s++)
+ {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else
+ {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0)
+ {
+ acc = neg ? LLONG_MIN : LLONG_MAX;
+ errno = ERANGE;
+ }
+ else if (neg)
+ acc *= -1;
+ if (endptr != 0)
+ *endptr = any ? (char *)s - 1 : (char *)nptr;
+ return acc;
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <libc/unconst.h>
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long
+strtoul(const char *nptr, char **endptr, int base)
+{
+ const char *s = nptr;
+ unsigned long acc;
+ int c;
+ unsigned long cutoff;
+ int neg = 0, any, cutlim;
+
+ /*
+ * See strtol for comments as to the logic used.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-')
+ {
+ neg = 1;
+ c = *s++;
+ }
+ else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X'))
+ {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
+ cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++)
+ {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0)
+ {
+ acc = ULONG_MAX;
+ errno = ERANGE;
+ }
+ else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = any ? unconst(s, char *) - 1 : unconst(nptr, char *);
+ return acc;
+}
--- /dev/null
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+//#include <libc/unconst.h>
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long
+strtoull(const char *nptr, char **endptr, int base)
+{
+ const char *s = nptr;
+ unsigned long acc;
+ int c;
+ unsigned long cutoff;
+ int neg = 0, any, cutlim;
+
+ /*
+ * See strtol for comments as to the logic used.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-')
+ {
+ neg = 1;
+ c = *s++;
+ }
+ else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X'))
+ {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ cutoff = (unsigned long)ULONG_MAX / base;
+ cutlim = (unsigned long)ULONG_MAX % base;
+ for (acc = 0, any = 0;; c = *s++)
+ {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0)
+ {
+ acc = ULONG_MAX;
+ errno = ERANGE;
+ }
+ else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = any ? (char *)s - 1 : (char *)nptr;
+ return acc;
+}
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+
#include <string.h>
-#include <libc/unconst.h>
void *
memchr(const void *s, int c, size_t n)
const char *p = s;
do {
if (*p++ == c)
- return unconst(p-1, void *);
+ return (void *)(p-1);
} while (--n != 0);
}
return 0;
--- /dev/null
+typedef unsigned int size_t;
+
+void *
+memcpy (char *to, char *from, size_t count);
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+void *
+memcpy (char *to, char *from, size_t count)
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+
+ return to;
+}
--- /dev/null
+#include <string.h>
+
+
+void * memmove(void *dest,const void *src,size_t count)
+{
+ int *int_dest = dest;
+ int *int_src = src;
+
+ while(count > 0 )
+ {
+ *int_dest = *int_src;
+ int_dest++;
+ int_src++;
+ count--;
+ }
+
+ return dest;
+
+
+}
\ No newline at end of file
--- /dev/null
+typedef int size_t;
+
+void * memset(void *src,int val,size_t count)
+{
+ int *int_src = src;
+ while(count>0) {
+ *int_src = val;
+ count--;
+ }
+ return src;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * string_old.c
+ *
+ * Oldnames from ANSI header string.h
+ *
+ * Some wrapper functions for those old name functions whose appropriate
+ * equivalents are not simply underscore prefixed.
+ *
+ * Contributors:
+ * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAMED. This includes but is not limited to warrenties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.1 $
+ * $Author: rex $
+ * $Date: 1999/01/16 02:11:44 $
+ *
+ */
+
+#include <string.h>
+#include <wchar.h>
+
+int
+strcasecmp (const char* sz1, const char* sz2)
+{
+ return stricmp (sz1, sz2);
+}
+
+int
+strncasecmp (const char* sz1, const char* sz2, size_t sizeMaxCompare)
+{
+ return strnicmp (sz1, sz2, sizeMaxCompare);
+}
+
+int
+wcscmpi (const wchar_t* ws1, const wchar_t* ws2)
+{
+ return wcsicmp (ws1, ws2);
+}
+
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <string.h>
-#include <libc/unconst.h>
-char *
-strchr(const char *s, int c)
+
+
+char *strchr(const char *s, int c);
+
+char *strchr(const char *s, int c)
{
char cc = c;
while (*s)
{
if (*s == cc)
- return unconst(s, char *);
+ return (char *)s;
s++;
}
if (cc == 0)
- return unconst(s, char *);
+ return (char *)s;
return 0;
}
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <string.h>
+char *
+strcpy(char *to, const char *from);
char *
strcpy(char *to, const char *from)
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <string.h>
-//#include <stdlib.h>
+#include <stdlib.h>
char *
strdup(const char *_s)
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+//#include <libc/unconst.h>
+
+
+char __syserr00[] = "No Error";
+char __syserr01[] = "Input to function out of range (EDOM)";
+char __syserr02[] = "Output of function out of range (ERANGE)";
+char __syserr03[] = "Argument list too long (E2BIG)";
+char __syserr04[] = "Permission denied (EACCES)";
+char __syserr05[] = "Resource temporarily unavailable (EAGAIN)";
+char __syserr06[] = "Bad file descriptor (EBADF)";
+char __syserr07[] = "Resource busy (EBUSY)";
+char __syserr08[] = "No child processes (ECHILD)";
+char __syserr09[] = "Resource deadlock avoided (EDEADLK)";
+char __syserr10[] = "File exists (EEXIST)";
+char __syserr11[] = "Bad address (EFAULT)";
+char __syserr12[] = "File too large (EFBIG)";
+char __syserr13[] = "Interrupted system call (EINTR)";
+char __syserr14[] = "Invalid argument (EINVAL)";
+char __syserr15[] = "Input or output error (EIO)";
+char __syserr16[] = "Is a directory (EISDIR)";
+char __syserr17[] = "Too many open files (EMFILE)";
+char __syserr18[] = "Too many links (EMLINK)";
+char __syserr19[] = "File name too long (ENAMETOOLONG)";
+char __syserr20[] = "Too many open files in system (ENFILE)";
+char __syserr21[] = "No such device (ENODEV)";
+char __syserr22[] = "No such file or directory (ENOENT)";
+char __syserr23[] = "Unable to execute file (ENOEXEC)";
+char __syserr24[] = "No locks available (ENOLCK)";
+char __syserr25[] = "Not enough memory (ENOMEM)";
+char __syserr26[] = "No space left on drive (ENOSPC)";
+char __syserr27[] = "Function not implemented (ENOSYS)";
+char __syserr28[] = "Not a directory (ENOTDIR)";
+char __syserr29[] = "Directory not empty (ENOTEMPTY)";
+char __syserr30[] = "Inappropriate I/O control operation (ENOTTY)";
+char __syserr31[] = "No such device or address (ENXIO)";
+char __syserr32[] = "Operation not permitted (EPERM)";
+char __syserr33[] = "Broken pipe (EPIPE)";
+char __syserr34[] = "Read-only file system (EROFS)";
+char __syserr35[] = "Invalid seek (ESPIPE)";
+char __syserr36[] = "No such process (ESRCH)";
+char __syserr37[] = "Improper link (EXDEV)";
+char __syserr38[] = "No more files (ENMFILE)";
+
+const char *__sys_errlist[] = {
+__syserr00, __syserr01, __syserr02, __syserr03, __syserr04,
+__syserr05, __syserr06, __syserr07, __syserr08, __syserr09,
+__syserr10, __syserr11, __syserr12, __syserr13, __syserr14,
+__syserr15, __syserr16, __syserr17, __syserr18, __syserr19,
+__syserr20, __syserr21, __syserr22, __syserr23, __syserr24,
+__syserr25, __syserr26, __syserr27, __syserr28, __syserr29,
+__syserr30, __syserr31, __syserr32, __syserr33, __syserr34,
+__syserr35, __syserr36, __syserr37, __syserr38
+};
+
+int __sys_nerr = sizeof(__sys_errlist) / sizeof(__sys_errlist[0]);
+
+char *
+strerror(int errnum)
+{
+ static char ebuf[40]; /* 64-bit number + slop */
+ char *cp;
+ int v=1000000, lz=0;
+
+ if (errnum >= 0 && errnum < __sys_nerr)
+ return((char *)__sys_errlist[errnum]);
+
+ strcpy(ebuf, "Unknown error: ");
+ cp = ebuf + 15;
+ if (errnum < 0)
+ {
+ *cp++ = '-';
+ errnum = -errnum;
+ }
+ while (v)
+ {
+ int d = errnum / v;
+ if (d || lz || (v == 1))
+ {
+ *cp++ = d+'0';
+ lz = 1;
+ }
+ errnum %= v;
+ v /= 10;
+ }
+
+ return ebuf;
+}
+
+#undef errno
+extern int errno;
+char *_strerror(const char *s)
+{
+ if ( s == NULL )
+ return strerror(errno);
+
+ return strerror(atoi(s));
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <string.h>
+#include <ctype.h>
+
+int
+stricmp(const char *s1, const char *s2)
+{
+ while (toupper(*s1) == toupper(*s2))
+ {
+ if (*s1 == 0)
+ return 0;
+ s1++;
+ s2++;
+ }
+ return toupper(*(unsigned const char *)s1) - toupper(*(unsigned const char *)(s2));
+}
--- /dev/null
+/*
+ * The C RunTime DLL
+ *
+ * Implements C run-time functionality as known from UNIX.
+ *
+ * Copyright 1996,1998 Marcus Meissner
+ * Copyright 1996 Jukka Iivonen
+ * Copyright 1997 Uwe Bonnes
+ */
+
+#include <string.h>
+#include <ctype.h>
+
+char * strlwr(char *x)
+{
+ char *y=x;
+
+ while (*y) {
+ *y=tolower(*y);
+ y++;
+ }
+ return x;
+}
\ No newline at end of file
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <string.h>
+
int
strncmp(const char *s1, const char *s2, size_t n)
{
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <string.h>
+#include <ctype.h>
+
+int
+strnicmp(const char *s1, const char *s2, size_t n)
+{
+
+ if (n == 0)
+ return 0;
+ do {
+ if (toupper(*s1) != toupper(*s2++))
+ return toupper(*(unsigned const char *)s1) - toupper(*(unsigned const char *)--s2);
+ if (*s1++ == 0)
+ break;
+ } while (--n != 0);
+ return 0;
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <string.h>
+
+size_t
+strnlen(const char *str, int count)
+{
+ const char *s;
+
+ if (str == 0)
+ return 0;
+ for (s = str; *s && count; ++s, count--);
+ return s-str;
+}
+
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <string.h>
-#include <libc/unconst.h>
+
char *
strpbrk(const char *s1, const char *s2)
{
for (scanp = s2; (sc = *scanp++) != 0;)
if (sc == c)
- return unconst(s1 - 1, char *);
+ return (char *)(s1 - 1);
}
return 0;
}
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <string.h>
-#include <libc/unconst.h>
+//#include <libc/unconst.h>
char *
strrchr(const char *s, int c)
}
if (cc == 0)
sp = s;
- return unconst(sp, char *);
+ return (char *)sp;
}
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <string.h>
-#include <libc/unconst.h>
+//#include <libc/unconst.h>
char *
strstr(const char *s, const char *find)
} while (strncmp(s, find, len) != 0);
s--;
}
- return unconst(s, char *);
+ return (char *)s;
}
--- /dev/null
+#include <string.h>
+#include <ctype.h>
+
+unsigned long strtoul(const char *cp,char **endp,unsigned int base)
+{
+ unsigned long result = 0,value;
+
+ if (!base) {
+ base = 10;
+ if (*cp == '0') {
+ base = 8;
+ cp++;
+ if ((*cp == 'x') && isxdigit(cp[1])) {
+ cp++;
+ base = 16;
+ }
+ }
+ }
+ while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+ ? toupper(*cp) : *cp)-'A'+10) < base) {
+ result = result*base + value;
+ cp++;
+ }
+ if (endp)
+ *endp = (char *)cp;
+ return result;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * The C RunTime DLL
+ *
+ * Implements C run-time functionality as known from UNIX.
+ *
+ * Copyright 1996,1998 Marcus Meissner
+ * Copyright 1996 Jukka Iivonen
+ * Copyright 1997 Uwe Bonnes
+ */
+
+
+#include <string.h>
+#include <ctype.h>
+
+char *strupr(char *x)
+{
+ char *y=x;
+
+ while (*y) {
+ *y=toupper(*y);
+ y++;
+ }
+ return x;
+}
#include <string.h>
size_t
-strxfrm(dst, src, n)
- char *dst;
- const char *src;
- size_t n;
+strxfrm(char *dst,const char *src, size_t n)
{
size_t r = 0;
int c;
--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <windows.h>
+#include <libc/file.h>
+
+void UnixTimeToFileTime( time_t unix_time, FILETIME *filetime, DWORD remainder );
+time_t FileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder );
+
+int
+fstat(int handle, struct stat *statbuf)
+{
+
+ BY_HANDLE_FILE_INFORMATION FileInformation;
+
+ if (!statbuf)
+ {
+
+ return -1;
+ }
+
+ if ( !GetFileInformationByHandle(filehnd(handle),&FileInformation) )
+ return -1;
+ statbuf->st_ctime = FileTimeToUnixTime( &FileInformation.ftCreationTime,NULL);
+ statbuf->st_atime = FileTimeToUnixTime( &FileInformation.ftLastAccessTime,NULL);
+ statbuf->st_mtime = FileTimeToUnixTime( &FileInformation.ftLastWriteTime,NULL);
+
+ statbuf->st_dev = handle;
+ statbuf->st_size = FileInformation.nFileSizeLow;
+ return 0;
+}
--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <io.h>
+
+#undef stat
+int stat( const char *path, struct stat *buffer )
+{
+ return _stat(path,buffer);
+}
+
+int _stat( const char *path, struct stat *buffer )
+{
+ int handle = _open(path,_O_RDONLY);
+ int ret;
+
+ ret = fstat(handle,buffer);
+ _close(handle);
+
+ return ret;
+
+}
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+/* This file has been modified by DJ Delorie. These modifications are
+** Copyright (C) 1995 DJ Delorie, 24 Kirsten Ave, Rochester NH,
+** 03867-2954, USA.
+*/
+
+/*
+ * Copyright (c) 1987, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Arthur David Olson of the National Cancer Institute.
+ *
+ * Redistribution and use in source and binary forms are permitted provided
+ * that: (1) source distributions retain this entire copyright notice and
+ * comment, and (2) distributions including binaries display the following
+ * acknowledgement: ``This product includes software developed by the
+ * University of California, Berkeley and its contributors'' in the
+ * documentation or other materials provided with the distribution and in
+ * all advertising materials mentioning features or use of this software.
+ * Neither the name of the University nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ctime.c 5.23 (Berkeley) 6/22/90";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu).
+** POSIX-style TZ environment variable handling from Guy Harris
+** (guy@auspex.com).
+*/
+
+
+#ifndef _TM_DEFINED
+struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ char *tm_zone;
+ int tm_gmtoff;
+};
+#define _TM_DEFINED
+#endif
+
+//#include <libc/stubs.h>
+#include <fcntl.h>
+#include <time.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <windows.h>
+//#include <unistd.h>
+#include "tzfile.h"
+
+//#include <libc/unconst.h>
+
+#include <io.h>
+
+#include "posixrul.h"
+
+#define P(s) s
+#define alloc_size_t size_t
+#define qsort_size_t size_t
+#define fread_size_t size_t
+#define fwrite_size_t size_t
+
+#define ACCESS_MODE O_RDONLY|O_BINARY
+#define OPEN_MODE O_RDONLY|O_BINARY
+
+/*
+** Someone might make incorrect use of a time zone abbreviation:
+** 1. They might reference tzname[0] before calling tzset (explicitly
+** or implicitly).
+** 2. They might reference tzname[1] before calling tzset (explicitly
+** or implicitly).
+** 3. They might reference tzname[1] after setting to a time zone
+** in which Daylight Saving Time is never observed.
+** 4. They might reference tzname[0] after setting to a time zone
+** in which Standard Time is never observed.
+** 5. They might reference tm.TM_ZONE after calling offtime.
+** What's best to do in the above cases is open to debate;
+** for now, we just set things up so that in any of the five cases
+** WILDABBR is used. Another possibility: initialize tzname[0] to the
+** string "tzname[0] used before set", and similarly for the other cases.
+** And another: initialize tzname[0] to "ERA", with an explanation in the
+** manual page of what this "time zone abbreviation" means (doing this so
+** that tzname[0] has the "normal" length of three characters).
+*/
+static char WILDABBR[] = " ";
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif /* !defined TRUE */
+
+static const char GMT[] = "GMT";
+
+struct ttinfo { /* time type information */
+ long tt_gmtoff; /* GMT offset in seconds */
+ int tt_isdst; /* used to set tm_isdst */
+ int tt_abbrind; /* abbreviation list index */
+ int tt_ttisstd; /* TRUE if transition is std time */
+};
+
+struct lsinfo { /* leap second information */
+ time_t ls_trans; /* transition time */
+ long ls_corr; /* correction to apply */
+};
+
+struct state {
+ int leapcnt;
+ int timecnt;
+ int typecnt;
+ int charcnt;
+ time_t ats[TZ_MAX_TIMES];
+ unsigned char types[TZ_MAX_TIMES];
+ struct ttinfo ttis[TZ_MAX_TYPES];
+ char chars[(TZ_MAX_CHARS + 1 > sizeof GMT) ? TZ_MAX_CHARS + 1 : sizeof GMT];
+ struct lsinfo lsis[TZ_MAX_LEAPS];
+};
+
+struct rule {
+ int r_type; /* type of rule--see below */
+ int r_day; /* day number of rule */
+ int r_week; /* week number of rule */
+ int r_mon; /* month number of rule */
+ long r_time; /* transition time of rule */
+};
+
+#define JULIAN_DAY 0 /* Jn - Julian day */
+#define DAY_OF_YEAR 1 /* n - day of year */
+#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
+
+/*
+** Prototypes for static functions.
+*/
+
+static long detzcode P((const char * codep));
+static const char * getzname P((const char * strp));
+static const char * getnum P((const char * strp, int * nump, int min,
+ int max));
+static const char * getsecs P((const char * strp, long * secsp));
+static const char * getoffset P((const char * strp, long * offsetp));
+static const char * getrule P((const char * strp, struct rule * rulep));
+static void gmtload P((struct state * sp));
+static void gmtsub P((const time_t * timep, long offset,
+ struct tm * tmp));
+static void localsub P((const time_t * timep, long offset,
+ struct tm * tmp));
+static void normalize P((int * tensptr, int * unitsptr, int base));
+static void settzname P((void));
+static time_t time1 P((struct tm * tmp, void (* funcp)(const time_t * const, const long, struct tm * const),
+ long offset));
+static time_t time2 P((struct tm *tmp, void (* funcp)(const time_t * const, const long, struct tm * const),
+ long offset, int * okayp));
+static void timesub P((const time_t * timep, long offset,
+ const struct state * sp, struct tm * tmp));
+static int tmcomp P((const struct tm * atmp,
+ const struct tm * btmp));
+static time_t transtime P((time_t janfirst, int year,
+ const struct rule * rulep, long offset));
+static int tzload P((const char * name, struct state * sp));
+static int tzparse P((const char * name, struct state * sp,
+ int lastditch));
+static void tzsetwall(void);
+
+#ifdef ALL_STATE
+static struct state *lclptr;
+static struct state *gmtptr;
+#endif /* defined ALL_STATE */
+
+#ifndef ALL_STATE
+static struct state lclmem;
+static struct state gmtmem;
+#define lclptr (&lclmem)
+#define gmtptr (&gmtmem)
+#endif /* State Farm */
+
+static int lcl_is_set;
+static int gmt_is_set;
+
+char * tzname[2] = {
+ WILDABBR,
+ WILDABBR
+};
+
+static long
+detzcode(const char * const codep)
+{
+ long result;
+ int i;
+
+ result = 0;
+ for (i = 0; i < 4; ++i)
+ result = (result << 8) | (codep[i] & 0xff);
+ return result;
+}
+
+static void
+settzname(void)
+{
+ const struct state * const sp = lclptr;
+ int i;
+
+ tzname[0] = WILDABBR;
+ tzname[1] = WILDABBR;
+#ifdef ALL_STATE
+ if (sp == NULL)
+ {
+ tzname[0] = tzname[1] = GMT;
+ return;
+ }
+#endif /* defined ALL_STATE */
+ for (i = 0; i < sp->typecnt; ++i)
+ {
+ register const struct ttinfo * const ttisp = &sp->ttis[i];
+
+ tzname[ttisp->tt_isdst] =
+ (char *)&sp->chars[ttisp->tt_abbrind];
+#if 0
+ if (ttisp->tt_isdst)
+ _daylight = 1;
+ if (i == 0 || !ttisp->tt_isdst)
+ _timezone = -(ttisp->tt_gmtoff);
+ if (i == 0 || ttisp->tt_isdst)
+ _altzone = -(ttisp->tt_gmtoff);
+#endif
+ }
+ /*
+ ** And to get the latest zone names into tzname. . .
+ */
+ for (i = 0; i < sp->timecnt; ++i)
+ {
+ const struct ttinfo * const ttisp = &sp->ttis[sp->types[i]];
+
+ tzname[ttisp->tt_isdst] = (char *)&sp->chars[ttisp->tt_abbrind];
+ }
+}
+
+static char *
+tzdir(void)
+{
+ static char dir[80]={0}, *cp;
+ if (dir[0] == 0)
+ {
+ if ((cp = getenv("TZDIR")))
+ {
+ strcpy(dir, cp);
+ }
+ else if ((cp = getenv("DJDIR")))
+ {
+ strcpy(dir, cp);
+ strcat(dir, "/zoneinfo");
+ }
+ else
+ strcpy(dir, "./");
+ }
+ return dir;
+}
+
+static int
+tzload(const char *name, struct state * const sp)
+{
+ const char * p;
+ int i;
+ int fid;
+ char fullname[FILENAME_MAX + 1];
+ const struct tzhead * tzhp;
+ char buf[sizeof *sp + sizeof *tzhp];
+ int ttisstdcnt;
+
+ if (name == NULL && (name = TZDEFAULT) == NULL)
+ return -1;
+
+ if (name[0] == ':')
+ ++name;
+ if (name[0] != '/')
+ {
+ if ((p = tzdir()) == NULL)
+ return -1;
+ if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
+ return -1;
+ strcpy(fullname, p);
+ strcat(fullname, "/");
+ strcat(fullname, name);
+ name = fullname;
+ }
+
+ if ((fid = open(name, OPEN_MODE)) == -1)
+ {
+ const char *base = strrchr(name, '/');
+ if (base)
+ base++;
+ else
+ base = name;
+ if (strcmp(base, "posixrules"))
+ return -1;
+
+ /* We've got a built-in copy of posixrules just in case */
+ memcpy(buf, _posixrules_data, sizeof(_posixrules_data));
+ i = sizeof(_posixrules_data);
+ }
+ else
+ {
+ i = read(fid, buf, sizeof buf);
+ if (close(fid) != 0 || i < sizeof *tzhp)
+ return -1;
+ }
+
+ tzhp = (struct tzhead *) buf;
+ ttisstdcnt = (int) detzcode(tzhp->tzh_ttisstdcnt);
+ sp->leapcnt = (int) detzcode(tzhp->tzh_leapcnt);
+ sp->timecnt = (int) detzcode(tzhp->tzh_timecnt);
+ sp->typecnt = (int) detzcode(tzhp->tzh_typecnt);
+ sp->charcnt = (int) detzcode(tzhp->tzh_charcnt);
+ if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
+ sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
+ sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
+ sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
+ (ttisstdcnt != sp->typecnt && ttisstdcnt != 0))
+ return -1;
+ if (i < sizeof *tzhp +
+ sp->timecnt * (4 + sizeof (char)) +
+ sp->typecnt * (4 + 2 * sizeof (char)) +
+ sp->charcnt * sizeof (char) +
+ sp->leapcnt * 2 * 4 +
+ ttisstdcnt * sizeof (char))
+ return -1;
+ p = buf + sizeof *tzhp;
+ for (i = 0; i < sp->timecnt; ++i)
+ {
+ sp->ats[i] = detzcode(p);
+ p += 4;
+ }
+ for (i = 0; i < sp->timecnt; ++i)
+ {
+ sp->types[i] = (unsigned char) *p++;
+ if (sp->types[i] >= sp->typecnt)
+ return -1;
+ }
+ for (i = 0; i < sp->typecnt; ++i)
+ {
+ struct ttinfo * ttisp;
+
+ ttisp = &sp->ttis[i];
+ ttisp->tt_gmtoff = detzcode(p);
+ p += 4;
+ ttisp->tt_isdst = (unsigned char) *p++;
+ if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
+ return -1;
+ ttisp->tt_abbrind = (unsigned char) *p++;
+ if (ttisp->tt_abbrind < 0 ||
+ ttisp->tt_abbrind > sp->charcnt)
+ return -1;
+ }
+ for (i = 0; i < sp->charcnt; ++i)
+ sp->chars[i] = *p++;
+ sp->chars[i] = '\0'; /* ensure '\0' at end */
+ for (i = 0; i < sp->leapcnt; ++i)
+ {
+ struct lsinfo * lsisp;
+
+ lsisp = &sp->lsis[i];
+ lsisp->ls_trans = detzcode(p);
+ p += 4;
+ lsisp->ls_corr = detzcode(p);
+ p += 4;
+ }
+ for (i = 0; i < sp->typecnt; ++i)
+ {
+ struct ttinfo * ttisp;
+
+ ttisp = &sp->ttis[i];
+ if (ttisstdcnt == 0)
+ ttisp->tt_ttisstd = FALSE;
+ else
+ {
+ ttisp->tt_ttisstd = *p++;
+ if (ttisp->tt_ttisstd != TRUE &&
+ ttisp->tt_ttisstd != FALSE)
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static const int mon_lengths[2][MONSPERYEAR] = {
+{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+static const int year_lengths[2] = {
+DAYSPERNYEAR, DAYSPERLYEAR
+};
+
+/*
+** Given a pointer into a time zone string, scan until a character that is not
+** a valid character in a zone name is found. Return a pointer to that
+** character.
+*/
+
+static const char *
+getzname(const char *strp)
+{
+ char c;
+
+ while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' &&
+ c != '+')
+ ++strp;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a number from that string.
+** Check that the number is within a specified range; if it is not, return
+** NULL.
+** Otherwise, return a pointer to the first character not part of the number.
+*/
+
+static const char *
+getnum(const char *strp, int * const nump, const int min, const int max)
+{
+ char c;
+ int num;
+
+ if (strp == NULL || !isdigit(*strp))
+ return NULL;
+ num = 0;
+ while ((c = *strp) != '\0' && isdigit(c))
+ {
+ num = num * 10 + (c - '0');
+ if (num > max)
+ return NULL;
+ ++strp;
+ }
+ if (num < min)
+ return NULL;
+ *nump = num;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a number of seconds,
+** in hh[:mm[:ss]] form, from the string.
+** If any error occurs, return NULL.
+** Otherwise, return a pointer to the first character not part of the number
+** of seconds.
+*/
+
+static const char *
+getsecs(const char *strp, long * const secsp)
+{
+ int num;
+
+ strp = getnum(strp, &num, 0, HOURSPERDAY);
+ if (strp == NULL)
+ return NULL;
+ *secsp = num * SECSPERHOUR;
+ if (*strp == ':')
+ {
+ ++strp;
+ strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
+ if (strp == NULL)
+ return NULL;
+ *secsp += num * SECSPERMIN;
+ if (*strp == ':')
+ {
+ ++strp;
+ strp = getnum(strp, &num, 0, SECSPERMIN - 1);
+ if (strp == NULL)
+ return NULL;
+ *secsp += num;
+ }
+ }
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract an offset, in
+** [+-]hh[:mm[:ss]] form, from the string.
+** If any error occurs, return NULL.
+** Otherwise, return a pointer to the first character not part of the time.
+*/
+
+static const char *
+getoffset(const char *strp, long * const offsetp)
+{
+ int neg;
+
+ if (*strp == '-')
+ {
+ neg = 1;
+ ++strp;
+ }
+ else if (isdigit(*strp) || *strp++ == '+')
+ neg = 0;
+ else
+ return NULL; /* illegal offset */
+ strp = getsecs(strp, offsetp);
+ if (strp == NULL)
+ return NULL; /* illegal time */
+ if (neg)
+ *offsetp = -*offsetp;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a rule in the form
+** date[/time]. See POSIX section 8 for the format of "date" and "time".
+** If a valid rule is not found, return NULL.
+** Otherwise, return a pointer to the first character not part of the rule.
+*/
+
+static const char *
+getrule(const char *strp, struct rule * const rulep)
+{
+ if (*strp == 'J')
+ {
+ /*
+ ** Julian day.
+ */
+ rulep->r_type = JULIAN_DAY;
+ ++strp;
+ strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
+ }
+ else if (*strp == 'M')
+ {
+ /*
+ ** Month, week, day.
+ */
+ rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
+ ++strp;
+ strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
+ if (strp == NULL)
+ return NULL;
+ if (*strp++ != '.')
+ return NULL;
+ strp = getnum(strp, &rulep->r_week, 1, 5);
+ if (strp == NULL)
+ return NULL;
+ if (*strp++ != '.')
+ return NULL;
+ strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
+ }
+ else if (isdigit(*strp))
+ {
+ /*
+ ** Day of year.
+ */
+ rulep->r_type = DAY_OF_YEAR;
+ strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
+ }
+ else
+ return NULL; /* invalid format */
+ if (strp == NULL)
+ return NULL;
+ if (*strp == '/')
+ {
+ /*
+ ** Time specified.
+ */
+ ++strp;
+ strp = getsecs(strp, &rulep->r_time);
+ }
+ else
+ rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
+ return strp;
+}
+
+/*
+** Given the Epoch-relative time of January 1, 00:00:00 GMT, in a year, the
+** year, a rule, and the offset from GMT at the time that rule takes effect,
+** calculate the Epoch-relative time that rule takes effect.
+*/
+
+static time_t
+transtime(const time_t janfirst, const int year, const struct rule * const rulep, const long offset)
+{
+ int leapyear;
+ time_t value=0;
+ int i;
+ int d, m1, yy0, yy1, yy2, dow;
+
+ leapyear = isleap(year);
+ switch (rulep->r_type)
+ {
+
+ case JULIAN_DAY:
+ /*
+ ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
+ ** years.
+ ** In non-leap years, or if the day number is 59 or less, just
+ ** add SECSPERDAY times the day number-1 to the time of
+ ** January 1, midnight, to get the day.
+ */
+ value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
+ if (leapyear && rulep->r_day >= 60)
+ value += SECSPERDAY;
+ break;
+
+ case DAY_OF_YEAR:
+ /*
+ ** n - day of year.
+ ** Just add SECSPERDAY times the day number to the time of
+ ** January 1, midnight, to get the day.
+ */
+ value = janfirst + rulep->r_day * SECSPERDAY;
+ break;
+
+ case MONTH_NTH_DAY_OF_WEEK:
+ /*
+ ** Mm.n.d - nth "dth day" of month m.
+ */
+ value = janfirst;
+ for (i = 0; i < rulep->r_mon - 1; ++i)
+ value += mon_lengths[leapyear][i] * SECSPERDAY;
+
+ /*
+ ** Use Zeller's Congruence to get day-of-week of first day of
+ ** month.
+ */
+ m1 = (rulep->r_mon + 9) % 12 + 1;
+ yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
+ yy1 = yy0 / 100;
+ yy2 = yy0 % 100;
+ dow = ((26 * m1 - 2) / 10 +
+ 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
+ if (dow < 0)
+ dow += DAYSPERWEEK;
+
+ /*
+ ** "dow" is the day-of-week of the first day of the month. Get
+ ** the day-of-month (zero-origin) of the first "dow" day of the
+ ** month.
+ */
+ d = rulep->r_day - dow;
+ if (d < 0)
+ d += DAYSPERWEEK;
+ for (i = 1; i < rulep->r_week; ++i)
+ {
+ if (d + DAYSPERWEEK >=
+ mon_lengths[leapyear][rulep->r_mon - 1])
+ break;
+ d += DAYSPERWEEK;
+ }
+
+ /*
+ ** "d" is the day-of-month (zero-origin) of the day we want.
+ */
+ value += d * SECSPERDAY;
+ break;
+ }
+
+ /*
+ ** "value" is the Epoch-relative time of 00:00:00 GMT on the day in
+ ** question. To get the Epoch-relative time of the specified local
+ ** time on that day, add the transition time and the current offset
+ ** from GMT.
+ */
+ return value + rulep->r_time + offset;
+}
+
+/*
+** Given a POSIX section 8-style TZ string, fill in the rule tables as
+** appropriate.
+*/
+
+static int
+tzparse(const char *name, struct state * const sp, const int lastditch)
+{
+ const char * stdname;
+ const char * dstname=0;
+ int stdlen;
+ int dstlen;
+ long stdoffset;
+ long dstoffset;
+ time_t * atp;
+ unsigned char * typep;
+ char * cp;
+ int load_result;
+
+ stdname = name;
+ if (lastditch)
+ {
+ stdlen = strlen(name); /* length of standard zone name */
+ name += stdlen;
+ if (stdlen >= sizeof sp->chars)
+ stdlen = (sizeof sp->chars) - 1;
+ }
+ else
+ {
+ name = getzname(name);
+ stdlen = name - stdname;
+ if (stdlen < 3)
+ return -1;
+ }
+ if (*name == '\0')
+ return -1;
+ else
+ {
+ name = getoffset(name, &stdoffset);
+ if (name == NULL)
+ return -1;
+ }
+ load_result = tzload(TZDEFRULES, sp);
+ if (load_result != 0)
+ sp->leapcnt = 0; /* so, we're off a little */
+ if (*name != '\0')
+ {
+ dstname = name;
+ name = getzname(name);
+ dstlen = name - dstname; /* length of DST zone name */
+ if (dstlen < 3)
+ return -1;
+ if (*name != '\0' && *name != ',' && *name != ';')
+ {
+ name = getoffset(name, &dstoffset);
+ if (name == NULL)
+ return -1;
+ }
+ else
+ dstoffset = stdoffset - SECSPERHOUR;
+ if (*name == ',' || *name == ';')
+ {
+ struct rule start;
+ struct rule end;
+ int year;
+ time_t janfirst;
+ time_t starttime;
+ time_t endtime;
+
+ ++name;
+ if ((name = getrule(name, &start)) == NULL)
+ return -1;
+ if (*name++ != ',')
+ return -1;
+ if ((name = getrule(name, &end)) == NULL)
+ return -1;
+ if (*name != '\0')
+ return -1;
+ sp->typecnt = 2; /* standard time and DST */
+ /*
+ ** Two transitions per year, from EPOCH_YEAR to 2037.
+ */
+ sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
+ if (sp->timecnt > TZ_MAX_TIMES)
+ return -1;
+ sp->ttis[0].tt_gmtoff = -dstoffset;
+ sp->ttis[0].tt_isdst = 1;
+ sp->ttis[0].tt_abbrind = stdlen + 1;
+ sp->ttis[1].tt_gmtoff = -stdoffset;
+ sp->ttis[1].tt_isdst = 0;
+ sp->ttis[1].tt_abbrind = 0;
+ atp = sp->ats;
+ typep = sp->types;
+ janfirst = 0;
+ for (year = EPOCH_YEAR; year <= 2037; ++year)
+ {
+ starttime = transtime(janfirst, year, &start,
+ stdoffset);
+ endtime = transtime(janfirst, year, &end,
+ dstoffset);
+ if (starttime > endtime)
+ {
+ *atp++ = endtime;
+ *typep++ = 1; /* DST ends */
+ *atp++ = starttime;
+ *typep++ = 0; /* DST begins */
+ }
+ else
+ {
+ *atp++ = starttime;
+ *typep++ = 0; /* DST begins */
+ *atp++ = endtime;
+ *typep++ = 1; /* DST ends */
+ }
+ janfirst +=
+ year_lengths[isleap(year)] * SECSPERDAY;
+ }
+ }
+ else
+ {
+ int sawstd;
+ int sawdst;
+ long stdfix;
+ long dstfix;
+ long oldfix;
+ int isdst;
+ int i;
+
+ if (*name != '\0')
+ return -1;
+ if (load_result != 0)
+ return -1;
+ /*
+ ** Compute the difference between the real and
+ ** prototype standard and summer time offsets
+ ** from GMT, and put the real standard and summer
+ ** time offsets into the rules in place of the
+ ** prototype offsets.
+ */
+ sawstd = FALSE;
+ sawdst = FALSE;
+ stdfix = 0;
+ dstfix = 0;
+ for (i = 0; i < sp->typecnt; ++i)
+ {
+ if (sp->ttis[i].tt_isdst)
+ {
+ oldfix = dstfix;
+ dstfix =
+ sp->ttis[i].tt_gmtoff + dstoffset;
+ if (sawdst && (oldfix != dstfix))
+ return -1;
+ sp->ttis[i].tt_gmtoff = -dstoffset;
+ sp->ttis[i].tt_abbrind = stdlen + 1;
+ sawdst = TRUE;
+ }
+ else
+ {
+ oldfix = stdfix;
+ stdfix =
+ sp->ttis[i].tt_gmtoff + stdoffset;
+ if (sawstd && (oldfix != stdfix))
+ return -1;
+ sp->ttis[i].tt_gmtoff = -stdoffset;
+ sp->ttis[i].tt_abbrind = 0;
+ sawstd = TRUE;
+ }
+ }
+ /*
+ ** Make sure we have both standard and summer time.
+ */
+ if (!sawdst || !sawstd)
+ return -1;
+ /*
+ ** Now correct the transition times by shifting
+ ** them by the difference between the real and
+ ** prototype offsets. Note that this difference
+ ** can be different in standard and summer time;
+ ** the prototype probably has a 1-hour difference
+ ** between standard and summer time, but a different
+ ** difference can be specified in TZ.
+ */
+ isdst = FALSE; /* we start in standard time */
+ for (i = 0; i < sp->timecnt; ++i)
+ {
+ const struct ttinfo * ttisp;
+
+ /*
+ ** If summer time is in effect, and the
+ ** transition time was not specified as
+ ** standard time, add the summer time
+ ** offset to the transition time;
+ ** otherwise, add the standard time offset
+ ** to the transition time.
+ */
+ ttisp = &sp->ttis[sp->types[i]];
+ sp->ats[i] +=
+ (isdst && !ttisp->tt_ttisstd) ?
+ dstfix : stdfix;
+ isdst = ttisp->tt_isdst;
+ }
+ }
+ }
+ else
+ {
+ dstlen = 0;
+ sp->typecnt = 1; /* only standard time */
+ sp->timecnt = 0;
+ sp->ttis[0].tt_gmtoff = -stdoffset;
+ sp->ttis[0].tt_isdst = 0;
+ sp->ttis[0].tt_abbrind = 0;
+ }
+ sp->charcnt = stdlen + 1;
+ if (dstlen != 0)
+ sp->charcnt += dstlen + 1;
+ if (sp->charcnt > sizeof sp->chars)
+ return -1;
+ cp = sp->chars;
+ (void) strncpy(cp, stdname, stdlen);
+ cp += stdlen;
+ *cp++ = '\0';
+ if (dstlen != 0)
+ {
+ (void) strncpy(cp, dstname, dstlen);
+ *(cp + dstlen) = '\0';
+ }
+ return 0;
+}
+
+static void
+gmtload(struct state * const sp)
+{
+ if (tzload(GMT, sp) != 0)
+ (void) tzparse(GMT, sp, TRUE);
+}
+
+void
+tzset(void)
+{
+ const char * name;
+
+ name = getenv("TZ");
+ if (name == NULL)
+ {
+ tzsetwall();
+ return;
+ }
+ lcl_is_set = TRUE;
+#ifdef ALL_STATE
+ if (lclptr == NULL)
+ {
+ lclptr = (struct state *) malloc(sizeof *lclptr);
+ if (lclptr == NULL)
+ {
+ settzname(); /* all we can do */
+ return;
+ }
+ }
+#endif /* defined ALL_STATE */
+ if (*name == '\0')
+ {
+ /*
+ ** User wants it fast rather than right.
+ */
+ lclptr->leapcnt = 0; /* so, we're off a little */
+ lclptr->timecnt = 0;
+ lclptr->ttis[0].tt_gmtoff = 0;
+ lclptr->ttis[0].tt_abbrind = 0;
+ (void) strcpy(lclptr->chars, GMT);
+ }
+ else if (tzload(name, lclptr) != 0)
+ if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
+ gmtload(lclptr);
+ settzname();
+}
+
+void
+tzsetwall(void)
+{
+ lcl_is_set = TRUE;
+#ifdef ALL_STATE
+ if (lclptr == NULL)
+ {
+ lclptr = (struct state *) malloc(sizeof *lclptr);
+ if (lclptr == NULL)
+ {
+ settzname(); /* all we can do */
+ return;
+ }
+ }
+#endif /* defined ALL_STATE */
+ if (tzload((char *) NULL, lclptr) != 0)
+ gmtload(lclptr);
+ settzname();
+}
+
+/*
+** The easy way to behave "as if no library function calls" localtime
+** is to not call it--so we drop its guts into "localsub", which can be
+** freely called. (And no, the PANS doesn't require the above behavior--
+** but it *is* desirable.)
+**
+** The unused offset argument is for the benefit of mktime variants.
+*/
+
+/*ARGSUSED*/
+static void
+localsub(const time_t * const timep, const long offset, struct tm * const tmp)
+{
+ const struct state * sp;
+ const struct ttinfo * ttisp;
+ int i;
+ const time_t t = *timep;
+
+ if (!lcl_is_set)
+ tzset();
+ sp = lclptr;
+#ifdef ALL_STATE
+ if (sp == NULL)
+ {
+ gmtsub(timep, offset, tmp);
+ return;
+ }
+#endif /* defined ALL_STATE */
+ if (sp->timecnt == 0 || t < sp->ats[0])
+ {
+ i = 0;
+ while (sp->ttis[i].tt_isdst)
+ if (++i >= sp->typecnt)
+ {
+ i = 0;
+ break;
+ }
+ }
+ else
+ {
+ for (i = 1; i < sp->timecnt; ++i)
+ if (t < sp->ats[i])
+ break;
+ i = sp->types[i - 1];
+ }
+ ttisp = &sp->ttis[i];
+ /*
+ ** To get (wrong) behavior that's compatible with System V Release 2.0
+ ** you'd replace the statement below with
+ ** t += ttisp->tt_gmtoff;
+ ** timesub(&t, 0L, sp, tmp);
+ */
+ timesub(&t, ttisp->tt_gmtoff, sp, tmp);
+ tmp->tm_isdst = ttisp->tt_isdst;
+ tzname[tmp->tm_isdst] = (char *)&sp->chars[ttisp->tt_abbrind];
+ tmp->tm_zone = (char *)&sp->chars[ttisp->tt_abbrind];
+}
+
+struct tm *
+localtime(const time_t * const timep)
+{
+ static struct tm tm;
+
+ localsub(timep, 0L, &tm);
+ return &tm;
+}
+
+/*
+** gmtsub is to gmtime as localsub is to localtime.
+*/
+
+static void
+gmtsub(const time_t * const timep, const long offset, struct tm * const tmp)
+{
+ if (!gmt_is_set)
+ {
+ gmt_is_set = TRUE;
+#ifdef ALL_STATE
+ gmtptr = (struct state *) malloc(sizeof *gmtptr);
+ if (gmtptr != NULL)
+#endif /* defined ALL_STATE */
+ gmtload(gmtptr);
+ }
+ timesub(timep, offset, gmtptr, tmp);
+ /*
+ ** Could get fancy here and deliver something such as
+ ** "GMT+xxxx" or "GMT-xxxx" if offset is non-zero,
+ ** but this is no time for a treasure hunt.
+ */
+ if (offset != 0)
+ tmp->tm_zone = WILDABBR;
+ else
+ {
+#ifdef ALL_STATE
+ if (gmtptr == NULL)
+ tmp->TM_ZONE = GMT;
+ else
+ tmp->TM_ZONE = gmtptr->chars;
+#endif /* defined ALL_STATE */
+#ifndef ALL_STATE
+ tmp->tm_zone = gmtptr->chars;
+#endif /* State Farm */
+ }
+}
+
+struct tm *
+gmtime(const time_t * const timep)
+{
+ static struct tm tm;
+
+ gmtsub(timep, 0L, &tm);
+ return &tm;
+}
+
+static void
+timesub(const time_t * const timep, const long offset, const struct state * const sp, struct tm * const tmp)
+{
+ const struct lsinfo * lp;
+ long days;
+ long rem;
+ int y;
+ int yleap;
+ const int * ip;
+ long corr;
+ int hit;
+ int i;
+
+ corr = 0;
+ hit = FALSE;
+#ifdef ALL_STATE
+ i = (sp == NULL) ? 0 : sp->leapcnt;
+#endif /* defined ALL_STATE */
+#ifndef ALL_STATE
+ i = sp->leapcnt;
+#endif /* State Farm */
+ while (--i >= 0)
+ {
+ lp = &sp->lsis[i];
+ if (*timep >= lp->ls_trans)
+ {
+ if (*timep == lp->ls_trans)
+ hit = ((i == 0 && lp->ls_corr > 0) ||
+ lp->ls_corr > sp->lsis[i - 1].ls_corr);
+ corr = lp->ls_corr;
+ break;
+ }
+ }
+ days = *timep / SECSPERDAY;
+ rem = *timep % SECSPERDAY;
+#ifdef mc68k
+ if (*timep == 0x80000000)
+ {
+ /*
+ ** A 3B1 muffs the division on the most negative number.
+ */
+ days = -24855;
+ rem = -11648;
+ }
+#endif /* mc68k */
+ rem += (offset - corr);
+ while (rem < 0)
+ {
+ rem += SECSPERDAY;
+ --days;
+ }
+ while (rem >= SECSPERDAY)
+ {
+ rem -= SECSPERDAY;
+ ++days;
+ }
+ tmp->tm_hour = (int) (rem / SECSPERHOUR);
+ rem = rem % SECSPERHOUR;
+ tmp->tm_min = (int) (rem / SECSPERMIN);
+ tmp->tm_sec = (int) (rem % SECSPERMIN);
+ if (hit)
+ /*
+ ** A positive leap second requires a special
+ ** representation. This uses "... ??:59:60".
+ */
+ ++(tmp->tm_sec);
+ tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
+ if (tmp->tm_wday < 0)
+ tmp->tm_wday += DAYSPERWEEK;
+ y = EPOCH_YEAR;
+ if (days >= 0)
+ for ( ; ; )
+ {
+ yleap = isleap(y);
+ if (days < (long) year_lengths[yleap])
+ break;
+ ++y;
+ days = days - (long) year_lengths[yleap];
+ }
+ else
+ do {
+ --y;
+ yleap = isleap(y);
+ days = days + (long) year_lengths[yleap];
+ } while (days < 0);
+ tmp->tm_year = y - TM_YEAR_BASE;
+ tmp->tm_yday = (int) days;
+ ip = mon_lengths[yleap];
+ for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
+ days = days - (long) ip[tmp->tm_mon];
+ tmp->tm_mday = (int) (days + 1);
+ tmp->tm_isdst = 0;
+ tmp->tm_gmtoff = offset;
+}
+
+/*
+** A la X3J11
+*/
+
+char *
+asctime(const struct tm *timeptr)
+{
+ static const char wday_name[DAYSPERWEEK][3] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+ static const char mon_name[MONSPERYEAR][3] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+ static char result[26];
+
+ (void) sprintf(result, "%.3s %.3s%3d %02d:%02d:%02d %d\n",
+ wday_name[timeptr->tm_wday],
+ mon_name[timeptr->tm_mon],
+ timeptr->tm_mday, timeptr->tm_hour,
+ timeptr->tm_min, timeptr->tm_sec,
+ TM_YEAR_BASE + timeptr->tm_year);
+ return result;
+}
+
+char *
+ctime(const time_t * const timep)
+{
+ return asctime(localtime(timep));
+}
+
+/*
+** Adapted from code provided by Robert Elz, who writes:
+** The "best" way to do mktime I think is based on an idea of Bob
+** Kridle's (so its said...) from a long time ago. (mtxinu!kridle now).
+** It does a binary search of the time_t space. Since time_t's are
+** just 32 bits, its a max of 32 iterations (even at 64 bits it
+** would still be very reasonable).
+*/
+
+#ifndef WRONG
+#define WRONG (-1)
+#endif /* !defined WRONG */
+
+static void
+normalize(int * const tensptr, int * const unitsptr, const int base)
+{
+ if (*unitsptr >= base)
+ {
+ *tensptr += *unitsptr / base;
+ *unitsptr %= base;
+ }
+ else if (*unitsptr < 0)
+ {
+ --*tensptr;
+ *unitsptr += base;
+ if (*unitsptr < 0)
+ {
+ *tensptr -= 1 + (-*unitsptr) / base;
+ *unitsptr = base - (-*unitsptr) % base;
+ }
+ }
+}
+
+static int
+tmcomp(const struct tm * const atmp, const struct tm * const btmp)
+{
+ int result;
+
+ if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
+ (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
+ (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
+ (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
+ (result = (atmp->tm_min - btmp->tm_min)) == 0)
+ result = atmp->tm_sec - btmp->tm_sec;
+ return result;
+}
+
+static time_t
+time2(struct tm *tmp, void (*const funcp)(const time_t *const,const long,struct tm *), const long offset, int * const okayp)
+{
+ const struct state * sp;
+ int dir;
+ int bits;
+ int i, j ;
+ int saved_seconds;
+ time_t newt;
+ time_t t;
+ struct tm yourtm, mytm;
+
+ *okayp = FALSE;
+ yourtm = *tmp;
+ if (yourtm.tm_sec >= SECSPERMIN + 2 || yourtm.tm_sec < 0)
+ normalize(&yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN);
+ normalize(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR);
+ normalize(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY);
+ normalize(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR);
+ while (yourtm.tm_mday <= 0)
+ {
+ --yourtm.tm_year;
+ yourtm.tm_mday +=
+ year_lengths[isleap(yourtm.tm_year + TM_YEAR_BASE)];
+ }
+ for ( ; ; )
+ {
+ i = mon_lengths[isleap(yourtm.tm_year +
+ TM_YEAR_BASE)][yourtm.tm_mon];
+ if (yourtm.tm_mday <= i)
+ break;
+ yourtm.tm_mday -= i;
+ if (++yourtm.tm_mon >= MONSPERYEAR)
+ {
+ yourtm.tm_mon = 0;
+ ++yourtm.tm_year;
+ }
+ }
+ saved_seconds = yourtm.tm_sec;
+ yourtm.tm_sec = 0;
+ /*
+ ** Calculate the number of magnitude bits in a time_t
+ ** (this works regardless of whether time_t is
+ ** signed or unsigned, though lint complains if unsigned).
+ */
+ for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
+ ;
+ /*
+ ** If time_t is signed, then 0 is the median value,
+ ** if time_t is unsigned, then 1 << bits is median.
+ */
+ t = (time_t) 1 << bits;
+ for ( ; ; )
+ {
+ (*funcp)(&t, offset, &mytm);
+ dir = tmcomp(&mytm, &yourtm);
+ if (dir != 0)
+ {
+ if (bits-- < 0)
+ return WRONG;
+ if (bits < 0)
+ --t;
+ else if (dir > 0)
+ t -= (time_t) 1 << bits;
+ else t += (time_t) 1 << bits;
+ continue;
+ }
+ if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
+ break;
+ /*
+ ** Right time, wrong type.
+ ** Hunt for right time, right type.
+ ** It's okay to guess wrong since the guess
+ ** gets checked.
+ */
+ sp = (const struct state *)
+ ((funcp == localsub) ? lclptr : gmtptr);
+#ifdef ALL_STATE
+ if (sp == NULL)
+ return WRONG;
+#endif /* defined ALL_STATE */
+ for (i = 0; i < sp->typecnt; ++i)
+ {
+ if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
+ continue;
+ for (j = 0; j < sp->typecnt; ++j)
+ {
+ if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
+ continue;
+ newt = t + sp->ttis[j].tt_gmtoff -
+ sp->ttis[i].tt_gmtoff;
+ (*funcp)(&newt, offset, &mytm);
+ if (tmcomp(&mytm, &yourtm) != 0)
+ continue;
+ if (mytm.tm_isdst != yourtm.tm_isdst)
+ continue;
+ /*
+ ** We have a match.
+ */
+ t = newt;
+ goto label;
+ }
+ }
+ return WRONG;
+ }
+ label:
+ t += saved_seconds;
+ (*funcp)(&t, offset, tmp);
+ *okayp = TRUE;
+ return t;
+}
+
+static time_t
+time1(struct tm * const tmp, void (*const funcp)(const time_t * const, const long, struct tm *), const long offset)
+{
+ time_t t;
+ const struct state * sp;
+ int samei, otheri;
+ int okay;
+
+ if (tmp->tm_isdst > 1)
+ tmp->tm_isdst = 1;
+ t = time2(tmp, funcp, offset, &okay);
+ if (okay || tmp->tm_isdst < 0)
+ return t;
+ /*
+ ** We're supposed to assume that somebody took a time of one type
+ ** and did some math on it that yielded a "struct tm" that's bad.
+ ** We try to divine the type they started from and adjust to the
+ ** type they need.
+ */
+ sp = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr);
+#ifdef ALL_STATE
+ if (sp == NULL)
+ return WRONG;
+#endif /* defined ALL_STATE */
+ for (samei = 0; samei < sp->typecnt; ++samei)
+ {
+ if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
+ continue;
+ for (otheri = 0; otheri < sp->typecnt; ++otheri)
+ {
+ if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
+ continue;
+ tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
+ sp->ttis[samei].tt_gmtoff;
+ tmp->tm_isdst = !tmp->tm_isdst;
+ t = time2(tmp, funcp, offset, &okay);
+ if (okay)
+ return t;
+ tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
+ sp->ttis[samei].tt_gmtoff;
+ tmp->tm_isdst = !tmp->tm_isdst;
+ }
+ }
+ return WRONG;
+}
+
+time_t
+mktime(struct tm * tmp)
+{
+ return time1(tmp, localsub, 0L);
+}
+
+
+time_t
+time(time_t *t)
+{
+ SYSTEMTIME SystemTime;
+ GetLocalTime(&SystemTime);
+
+
+}
+
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <time.h>
+
+double
+difftime(time_t time1, time_t time0)
+{
+ return time1-time0;
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+/* generated with bin2h from DJGPP/zoneinfo/posixrules */
+
+unsigned char _posixrules_data[] = {
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,
+0,1,16,0,0,0,2,0,0,0,8,0,151,254,240,1,135,225,224,2,119,224,240,3,112,254,96,4,96,253,112,5,80,
+224,96,6,64,223,112,7,48,194,96,7,141,25,112,9,16,164,96,9,173,148,240,10,240,134,96,11,224,133,112,12,217,162,
+224,13,192,103,112,14,185,132,224,15,169,131,240,16,153,102,224,17,137,101,240,18,121,72,224,19,105,71,240,20,89,42,224,
+21,73,41,240,22,57,12,224,23,41,11,240,24,34,41,96,25,8,237,240,26,2,11,96,26,242,10,112,27,225,237,96,28,
+209,236,112,29,193,207,96,30,177,206,112,31,161,177,96,32,118,0,240,33,129,147,96,34,85,226,240,35,106,175,224,36,53,
+196,240,37,74,145,224,38,21,166,240,39,42,115,224,39,254,195,112,41,10,85,224,41,222,165,112,42,234,55,224,43,190,135,
+112,44,211,84,96,45,158,105,112,46,179,54,96,47,126,75,112,48,147,24,96,49,103,103,240,50,114,250,96,51,71,73,240,
+52,82,220,96,53,39,43,240,54,50,190,96,55,7,13,240,56,27,218,224,56,230,239,240,57,251,188,224,58,198,209,240,59,
+219,158,224,60,175,238,112,61,187,128,224,62,143,208,112,63,155,98,224,64,111,178,112,65,132,127,96,66,79,148,112,67,100,
+97,96,68,47,118,112,69,68,67,96,70,15,88,112,71,36,37,96,71,248,116,240,73,4,7,96,73,216,86,240,74,227,233,
+96,75,184,56,240,76,205,5,224,77,152,26,240,78,172,231,224,79,119,252,240,80,140,201,224,81,97,25,112,82,108,171,224,
+83,64,251,112,84,76,141,224,85,32,221,112,86,44,111,224,87,0,191,112,88,21,140,96,88,224,161,112,89,245,110,96,90,
+192,131,112,91,213,80,96,92,169,159,240,93,181,50,96,94,137,129,240,95,149,20,96,96,105,99,240,97,126,48,224,98,73,
+69,240,99,94,18,224,100,41,39,240,101,61,244,224,102,18,68,112,103,29,214,224,103,242,38,112,104,253,184,224,105,210,8,
+112,106,221,154,224,107,177,234,112,108,198,183,96,109,145,204,112,110,166,153,96,111,113,174,112,112,134,123,96,113,90,202,240,
+114,102,93,96,115,58,172,240,116,70,63,96,117,26,142,240,118,47,91,224,118,250,112,240,120,15,61,224,120,218,82,240,121,
+239,31,224,122,186,52,240,123,207,1,224,124,163,81,112,125,174,227,224,126,131,51,112,127,142,197,224,128,99,21,112,129,119,
+226,96,130,66,247,112,131,87,196,96,132,34,217,112,133,55,166,96,134,11,245,240,135,23,136,96,135,235,215,240,136,247,106,
+96,137,203,185,240,138,215,76,96,139,171,155,240,140,192,104,224,141,139,125,240,142,160,74,224,143,107,95,240,144,128,44,224,
+145,84,124,112,146,96,14,224,147,52,94,112,148,63,240,224,149,20,64,112,150,41,13,96,150,244,34,112,152,8,239,96,152,
+212,4,112,153,232,209,96,154,189,32,240,155,200,179,96,156,157,2,240,157,168,149,96,158,124,228,240,159,136,119,96,160,92,
+198,240,161,113,147,224,162,60,168,240,163,81,117,224,164,28,138,240,165,49,87,224,166,5,167,112,167,17,57,224,167,229,137,
+112,168,241,27,224,169,197,107,112,170,218,56,96,171,165,77,112,172,186,26,96,173,133,47,112,174,153,252,96,175,101,17,112,
+176,121,222,96,177,78,45,240,178,89,192,96,179,46,15,240,180,57,162,96,181,13,241,240,182,34,190,224,182,237,211,240,184,
+2,160,224,184,205,181,240,185,226,130,224,186,182,210,112,187,194,100,224,188,150,180,112,189,162,70,224,190,118,150,112,191,130,
+40,224,192,86,120,112,193,107,69,96,194,54,90,112,195,75,39,96,196,22,60,112,197,43,9,96,197,255,88,240,199,10,235,
+96,199,223,58,240,200,234,205,96,201,191,28,240,202,211,233,224,203,158,254,240,204,179,203,224,205,126,224,240,206,147,173,224,
+207,103,253,112,208,115,143,224,209,71,223,112,210,83,113,224,211,39,193,112,212,51,83,224,213,7,163,112,214,28,112,96,214,
+231,133,112,215,252,82,96,216,199,103,112,217,220,52,96,218,176,131,240,219,188,22,96,220,144,101,240,221,155,248,96,222,112,
+71,240,223,133,20,224,224,80,41,240,225,100,246,224,226,48,11,240,227,68,216,224,228,15,237,240,229,36,186,224,229,249,10,
+112,231,4,156,224,231,216,236,112,232,228,126,224,233,184,206,112,234,205,155,96,235,152,176,112,236,173,125,96,237,120,146,112,
+238,141,95,96,239,97,174,240,240,109,65,96,241,65,144,240,242,77,35,96,243,33,114,240,244,45,5,96,245,1,84,240,246,
+22,33,224,246,225,54,240,247,246,3,224,248,193,24,240,249,213,229,224,250,160,250,240,251,181,199,224,252,138,23,112,253,149,
+169,224,254,105,249,112,255,117,139,224,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,
+1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
+0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,
+1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
+0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,
+1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
+0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,
+1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
+0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,255,255,199,192,1,0,255,255,185,176,0,4,69,68,84,
+0,69,83,84,0,0,0
+};
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <string.h>
+#ifndef _TM_DEFINED
+struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ char *tm_zone;
+ int tm_gmtoff;
+};
+#define _TM_DEFINED
+#endif
+
+#include <time.h>
+
+#define TM_YEAR_BASE 1900
+
+static const char *afmt[] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
+};
+static const char *Afmt[] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
+ "Saturday",
+};
+static const char *bfmt[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
+ "Oct", "Nov", "Dec",
+};
+static const char *Bfmt[] = {
+ "January", "February", "March", "April", "May", "June", "July",
+ "August", "September", "October", "November", "December",
+};
+
+static size_t gsize;
+static char *pt;
+
+static int
+_add(const char *str)
+{
+ for (;; ++pt, --gsize)
+ {
+ if (!gsize)
+ return 0;
+ if (!(*pt = *str++))
+ return 1;
+ }
+}
+
+static int
+_conv(int n, int digits, char pad)
+{
+ static char buf[10];
+ char *p;
+
+ for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
+ *p-- = n % 10 + '0';
+ while (p > buf && digits-- > 0)
+ *p-- = pad;
+ return _add(++p);
+}
+
+static size_t
+_fmt(const char *format, const struct tm *t)
+{
+ for (; *format; ++format)
+ {
+ if (*format == '%')
+ switch(*++format)
+ {
+ case '\0':
+ --format;
+ break;
+ case 'A':
+ if (t->tm_wday < 0 || t->tm_wday > 6)
+ return 0;
+ if (!_add(Afmt[t->tm_wday]))
+ return 0;
+ continue;
+ case 'a':
+ if (t->tm_wday < 0 || t->tm_wday > 6)
+ return 0;
+ if (!_add(afmt[t->tm_wday]))
+ return 0;
+ continue;
+ case 'B':
+ if (t->tm_mon < 0 || t->tm_mon > 11)
+ return 0;
+ if (!_add(Bfmt[t->tm_mon]))
+ return 0;
+ continue;
+ case 'b':
+ case 'h':
+ if (t->tm_mon < 0 || t->tm_mon > 11)
+ return 0;
+ if (!_add(bfmt[t->tm_mon]))
+ return 0;
+ continue;
+ case 'C':
+ if (!_fmt("%a %b %e %H:%M:%S %Y", t))
+ return 0;
+ continue;
+ case 'c':
+ if (!_fmt("%m/%d/%y %H:%M:%S", t))
+ return 0;
+ continue;
+ case 'e':
+ if (!_conv(t->tm_mday, 2, ' '))
+ return 0;
+ continue;
+ case 'D':
+ if (!_fmt("%m/%d/%y", t))
+ return 0;
+ continue;
+ case 'd':
+ if (!_conv(t->tm_mday, 2, '0'))
+ return 0;
+ continue;
+ case 'H':
+ if (!_conv(t->tm_hour, 2, '0'))
+ return 0;
+ continue;
+ case 'I':
+ if (!_conv(t->tm_hour % 12 ?
+ t->tm_hour % 12 : 12, 2, '0'))
+ return 0;
+ continue;
+ case 'j':
+ if (!_conv(t->tm_yday + 1, 3, '0'))
+ return 0;
+ continue;
+ case 'k':
+ if (!_conv(t->tm_hour, 2, ' '))
+ return 0;
+ continue;
+ case 'l':
+ if (!_conv(t->tm_hour % 12 ?
+ t->tm_hour % 12 : 12, 2, ' '))
+ return 0;
+ continue;
+ case 'M':
+ if (!_conv(t->tm_min, 2, '0'))
+ return 0;
+ continue;
+ case 'm':
+ if (!_conv(t->tm_mon + 1, 2, '0'))
+ return 0;
+ continue;
+ case 'n':
+ if (!_add("\n"))
+ return 0;
+ continue;
+ case 'p':
+ if (!_add(t->tm_hour >= 12 ? "PM" : "AM"))
+ return 0;
+ continue;
+ case 'R':
+ if (!_fmt("%H:%M", t))
+ return 0;
+ continue;
+ case 'r':
+ if (!_fmt("%I:%M:%S %p", t))
+ return 0;
+ continue;
+ case 'S':
+ if (!_conv(t->tm_sec, 2, '0'))
+ return 0;
+ continue;
+ case 'T':
+ case 'X':
+ if (!_fmt("%H:%M:%S", t))
+ return 0;
+ continue;
+ case 't':
+ if (!_add("\t"))
+ return 0;
+ continue;
+ case 'U':
+ if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7,
+ 2, '0'))
+ return 0;
+ continue;
+ case 'W':
+ if (!_conv((t->tm_yday + 7 -
+ (t->tm_wday ? (t->tm_wday - 1) : 6))
+ / 7, 2, '0'))
+ return 0;
+ continue;
+ case 'w':
+ if (!_conv(t->tm_wday, 1, '0'))
+ return 0;
+ continue;
+ case 'x':
+ if (!_fmt("%m/%d/%y", t))
+ return 0;
+ continue;
+ case 'y':
+ if (!_conv((t->tm_year + TM_YEAR_BASE)
+ % 100, 2, '0'))
+ return 0;
+ continue;
+ case 'Y':
+ if (!_conv(t->tm_year + TM_YEAR_BASE, 4, '0'))
+ return 0;
+ continue;
+ case 'Z':
+ if (!t->tm_zone || !_add(t->tm_zone))
+ return 0;
+ continue;
+ case '%':
+ /*
+ * X311J/88-090 (4.12.3.5): if conversion char is
+ * undefined, behavior is undefined. Print out the
+ * character itself as printf(3) does.
+ */
+ default:
+ break;
+ }
+ if (!gsize--)
+ return 0;
+ *pt++ = *format;
+ }
+ return gsize;
+}
+
+size_t
+strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
+{
+ pt = s;
+ if ((gsize = maxsize) < 1)
+ return 0;
+ if (_fmt(format, t))
+ {
+ *pt = '\0';
+ return maxsize - gsize;
+ }
+ return 0;
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#ifndef _TM_DEFINED
+struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ char *tm_zone;
+ int tm_gmtoff;
+};
+#define _TM_DEFINED
+#endif
+
+#include <time.h>
+#include <windows.h>
+
+
+time_t
+time(time_t *t)
+{
+ SYSTEMTIME SystemTime;
+ GetLocalTime(&SystemTime);
+
+
+}
--- /dev/null
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#ifndef __dj_include_tzfile_h__
+#define __dj_include_tzfile_h__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _POSIX_SOURCE
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Arthur David Olson of the National Cancer Institute.
+ *
+ * Redistribution and use in source and binary forms are permitted provided
+ * that: (1) source distributions retain this entire copyright notice and
+ * comment, and (2) distributions including binaries display the following
+ * acknowledgement: ``This product includes software developed by the
+ * University of California, Berkeley and its contributors'' in the
+ * documentation or other materials provided with the distribution and in
+ * all advertising materials mentioning features or use of this software.
+ * Neither the name of the University nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)tzfile.h 5.9 (Berkeley) 6/11/90
+ */
+
+/*
+** Information about time zone files.
+*/
+
+ /* Time zone object file directory */
+#define TZDIR "/usr/share/zoneinfo"
+#define TZDEFAULT "/etc/localtime"
+#define TZDEFRULES "posixrules"
+
+/*
+** Each file begins with. . .
+*/
+
+struct tzhead {
+ char tzh_reserved[24]; /* reserved for future use */
+ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
+ char tzh_leapcnt[4]; /* coded number of leap seconds */
+ char tzh_timecnt[4]; /* coded number of transition times */
+ char tzh_typecnt[4]; /* coded number of local time types */
+ char tzh_charcnt[4]; /* coded number of abbr. chars */
+};
+
+/*
+** . . .followed by. . .
+**
+** tzh_timecnt (char [4])s coded transition times a la time(2)
+** tzh_timecnt (unsigned char)s types of local time starting at above
+** tzh_typecnt repetitions of
+** one (char [4]) coded GMT offset in seconds
+** one (unsigned char) used to set tm_isdst
+** one (unsigned char) that's an abbreviation list index
+** tzh_charcnt (char)s '\0'-terminated zone abbreviations
+** tzh_leapcnt repetitions of
+** one (char [4]) coded leap second transition times
+** one (char [4]) total correction after above
+** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
+** time is standard time, if FALSE,
+** transition time is wall clock time
+** if absent, transition times are
+** assumed to be wall clock time
+*/
+
+/*
+** In the current implementation, "tzset()" refuses to deal with files that
+** exceed any of the limits below.
+*/
+
+/*
+** The TZ_MAX_TIMES value below is enough to handle a bit more than a
+** year's worth of solar time (corrected daily to the nearest second) or
+** 138 years of Pacific Presidential Election time
+** (where there are three time zone transitions every fourth year).
+*/
+#define TZ_MAX_TIMES 370
+
+#define NOSOLAR /* 4BSD doesn't currently handle solar time */
+
+#ifndef NOSOLAR
+#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
+#else
+#define TZ_MAX_TYPES 10 /* Maximum number of local time types */
+#endif
+
+#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
+
+#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
+
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define HOURSPERDAY 24
+#define DAYSPERWEEK 7
+#define DAYSPERNYEAR 365
+#define DAYSPERLYEAR 366
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR 12
+
+#define TM_SUNDAY 0
+#define TM_MONDAY 1
+#define TM_TUESDAY 2
+#define TM_WEDNESDAY 3
+#define TM_THURSDAY 4
+#define TM_FRIDAY 5
+#define TM_SATURDAY 6
+
+#define TM_JANUARY 0
+#define TM_FEBRUARY 1
+#define TM_MARCH 2
+#define TM_APRIL 3
+#define TM_MAY 4
+#define TM_JUNE 5
+#define TM_JULY 6
+#define TM_AUGUST 7
+#define TM_SEPTEMBER 8
+#define TM_OCTOBER 9
+#define TM_NOVEMBER 10
+#define TM_DECEMBER 11
+
+#define TM_YEAR_BASE 1900
+
+#define EPOCH_YEAR 1970
+#define EPOCH_WDAY TM_THURSDAY
+
+/*
+** Accurate only for the past couple of centuries;
+** that will probably do.
+*/
+
+#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifndef __dj_ENFORCE_FUNCTION_CALLS
+#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __dj_include_tzfile_h__ */
--- /dev/null
+
+
+#include <wstring.h>
+
+wchar_t * wcscat(wchar_t * dest,const wchar_t * src)
+{
+
+ int i,j;
+ j=0;
+ for (i=0; dest[i]!=0; i++);
+ while (src[j] != 0)
+ {
+ dest[i+j] = src[j];
+ j++;
+ }
+ dest[i+j] = 0;
+ return dest;
+}
+
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+#include <wstring.h>
+
+wchar_t* wcschr(const wchar_t* str, wchar_t ch)
+{
+ while ((*str)!=0)
+ {
+ if ((*str)==ch)
+ {
+ return((wchar_t *)str);
+ }
+ str++;
+ }
+ return(NULL);
+}
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+#include <wstring.h>
+
+int wcscmp(const wchar_t* cs,const wchar_t * ct)
+{
+ while (*cs == *ct)
+ {
+ if (*cs == 0)
+ return 0;
+ cs++;
+ ct++;
+ }
+ return *cs - *ct;
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * The C RunTime DLL
+ *
+ * Implements C run-time functionality as known from UNIX.
+ *
+ * Copyright 1996,1998 Marcus Meissner
+ * Copyright 1996 Jukka Iivonen
+ * Copyright 1997 Uwe Bonnes
+ */
+
+#include <wstring.h>
+
+size_t wcscoll(wchar_t *a1,wchar_t *a2)
+{
+ /* FIXME: handle collates */
+ return wcscmp(a1,a2);
+}
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+#include <wstring.h>
+
+wchar_t * wcscpy(wchar_t * str1,const wchar_t * str2)
+{
+ wchar_t *save = str1;
+
+ for (; (*str1 = *str2); ++str2, ++str1);
+ return save;
+}
\ No newline at end of file
--- /dev/null
+#include <wstring.h>
+
+size_t wcscspn(const wchar_t *str,const wchar_t *reject)
+{
+ wchar_t *s;
+ wchar_t *t;
+ s=(wchar_t *)str;
+ do {
+ t=(wchar_t *)reject;
+ while (*t) {
+ if (*t==*s)
+ break;
+ t++;
+ }
+ if (*t)
+ break;
+ s++;
+ } while (*s);
+ return s-str; /* nr of wchars */
+}
\ No newline at end of file
--- /dev/null
+#include <wstring.h>
+
+
+wchar_t *wcsdup(const wchar_t *ptr)
+{
+ wchar_t *dup;
+ dup = malloc((wcslen(ptr) + 1)*sizeof(wchar_t));
+ if( dup == NULL )
+ return NULL;
+ wcscpy(dup,ptr);
+ return dup;
+}
+
+
+
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+#include <wstring.h>
+
+int wcsicmp(const wchar_t* cs,const wchar_t * ct)
+{
+ while (towlower(*cs) == towlower(*ct))
+ {
+ if (*cs == 0)
+ return 0;
+ cs++;
+ ct++;
+ }
+ return towlower(*cs) - towlower(*ct);
+
+}
\ No newline at end of file
--- /dev/null
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
+#include <wstring.h>
+
+size_t wstrlen(const wchar_t *s)
+{
+ return wcslen(s);
+}
+
+
+size_t wcslen(const wchar_t * s)
+{
+ const wchar_t *save;
+
+ if (s == 0)
+ return 0;
+ for (save = s; *save; ++save);
+ return save-s;
+}
--- /dev/null
+/*
+ * The C RunTime DLL
+ *
+ * Implements C run-time functionality as known from UNIX.
+ *
+ * Copyright 1996,1998 Marcus Meissner
+ * Copyright 1996 Jukka Iivonen
+ * Copyright 1997 Uwe Bonnes
+ */
+
+#include <wstring.h>
+
+wchar_t * wcslwr(wchar_t *x)
+{
+ wchar_t *y=x;
+
+ while (*y) {
+ *y=towlower(*y);
+ y++;
+ }
+ return x;
+}
\ No newline at end of file
--- /dev/null
+#include <wstring.h>
+
+wchar_t * wcsncat(wchar_t * dest,const wchar_t * src,size_t count)
+{
+ int i,j;
+ if ( count != 0 ) {
+
+ for (j=0;dest[j]!=0;j++);
+
+ for (i=0;i<count;i++)
+ {
+ dest[j+i] = src[i];
+ if (src[i] == 0)
+ return(dest);
+
+ }
+ dest[j+i]=0;
+ }
+ return(dest);
+}
--- /dev/null
+#include <wstring.h>
+
+int wcsncmp(const wchar_t * cs,const wchar_t * ct,size_t count)
+{
+ while ((*cs) == (*ct) && count > 0)
+ {
+ if (*cs == 0)
+ return 0;
+ cs++;
+ ct++;
+ count--;
+ }
+ return (*cs) - (*ct);
+
+}
+
--- /dev/null
+#include <wstring.h>
+
+wchar_t * wcsncpy(wchar_t * dest,const wchar_t *src,size_t count)
+{
+ int i;
+
+ for (i=0;i<count;i++)
+ {
+ dest[i] = src[i];
+ if (src[i] == 0)
+ {
+ return(dest);
+ }
+ }
+ dest[i]=0;
+ return(dest);
+}
+
+
+
+
--- /dev/null
+#include <wstring.h>
+
+int wcsnicmp(const wchar_t * cs,const wchar_t * ct,size_t count)
+{
+ wchar_t *save = cs;
+ while (towlower(*cs) == towlower(*ct) && (int)(cs - save) < count)
+ {
+ if (*cs == 0)
+ return 0;
+ cs++;
+ ct++;
+ }
+ return towlower(*cs) - towlower(*ct);
+
+}
--- /dev/null
+size_t wcsnlen(const wchar_t * s, size_t count)
+{
+
+ unsigned int len=0;
+
+ while(s[len]!=0 && len < count) {
+ len++;
+ };
+ return len;
+}
--- /dev/null
+wchar_t* wcsrchr(const wchar_t* str, wchar_t ch)
+{
+
+ wchar_t *sp=(wchar_t *)0;
+ while (*str != 0)
+ {
+ if (*str == ch)
+ sp = (wchar_t *)str;
+ str++;
+ }
+ if (ch == 0)
+ sp = (wchar_t *)str;
+ return sp;
+}
\ No newline at end of file
--- /dev/null
+wchar_t * wcsrev(wchar_t *s)
+{
+ wchar_t *e;
+ wchar_t a;
+ e=s;
+ while (*e)
+ e++;
+ while (s<e) {
+ a=*s;
+ *s=*e;
+ *e=a;
+ s++;
+ e--;
+ }
+ return s;
+}
\ No newline at end of file
--- /dev/null
+size_t wcsspn(const wchar_t *str,const wchar_t *accept)
+{
+ wchar_t *s;
+ wchar_t *t;
+ s=(wchar_t *)str;
+ do {
+ t=(wchar_t *)accept;
+ while (*t) {
+ if (*t==*s)
+ break;
+ t++;
+ }
+ if (!*t)
+ break;
+ s++;
+ } while (*s);
+ return s-str; /* nr of wchars */
+}
\ No newline at end of file
--- /dev/null
+wchar_t *wcsstr(const wchar_t *s,const wchar_t *b)
+{
+ wchar_t *x;
+ wchar_t *y;
+ wchar_t *c;
+ x=(wchar_t *)s;
+ while (*x) {
+ if (*x==*b) {
+ y=x;
+ c=(wchar_t *)b;
+ while (*y && *c && *y==*c) {
+ c++;
+ y++;
+ }
+ if (!*c)
+ return x;
+ }
+ x++;
+ }
+ return NULL;
+}
\ No newline at end of file
--- /dev/null
+wchar_t *wcstok(wchar_t *s, const wchar_t *ct)
+{
+ const wchar_t *spanp;
+ int c, sc;
+ wchar_t *tok;
+ static wchar_t *last;
+
+
+ if (s == NULL && (s = last) == NULL)
+ return (NULL);
+
+ /*
+ * Skip (span) leading ctiters (s += strspn(s, ct), sort of).
+ */
+ cont:
+ c = *s;
+ s++;
+ for (spanp = ct; (sc = *spanp) != 0;spanp++) {
+ if (c == sc)
+ goto cont;
+ }
+
+ if (c == 0) { /* no non-ctiter characters */
+ last = NULL;
+ return (NULL);
+ }
+ tok = s - 2;
+
+ /*
+ * Scan token (scan for ctiters: s += strcspn(s, ct), sort of).
+ * Note that ct must have one NUL; we stop if we see that, too.
+ */
+ for (;;) {
+
+ c = *s;
+ s+=2;
+ spanp = ct;
+ do {
+ if ((sc = *spanp) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ last = s;
+ return (tok);
+ }
+ spanp+=2;
+ } while (sc != 0);
+
+ }
+ /* NOTREACHED */
+}
\ No newline at end of file
--- /dev/null
+unsigned long wcstoul(const wchar_t *cp,wchar_t **endp,unsigned int base)
+{
+ unsigned long result = 0,value;
+
+ if (!base) {
+ base = 10;
+ if (*cp == L'0') {
+ base = 8;
+ cp++;
+ if ((*cp == L'x') && iswxdigit(cp[1])) {
+ cp++;
+ base = 16;
+ }
+ }
+ }
+ while (iswxdigit(*cp) && (value = iswdigit(*cp) ? *cp-L'0' : (iswlower(*cp)
+ ? towupper(*cp) : *cp)-L'A'+10) < base) {
+ result = result*base + value;
+ cp++;
+ }
+ if (endp)
+ *endp = (wchar_t *)cp;
+ return result;
+}
+
--- /dev/null
+// copy a wide character string to a multibyte string
+size_t __cdecl wcstombs( char *dst, const wchar_t *src, size_t len )
+{
+ lstrcpynWtoA( dst, src, len );
+ return strlen(dst); /* FIXME: is this right? */
+}
\ No newline at end of file
--- /dev/null
+wchar_t *wcsupr(wchar_t *x)
+{
+ wchar_t *y=x;
+
+ while (*y) {
+ *y=towupper(*y);
+ y++;
+ }
+ return x;
+}
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/file/create.c
- * PURPOSE: File create/open functions
+ * PURPOSE: Directory functions
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
- * GetTempFileName is modified from WINE [ Alexandre Juiliard ]
+ GetTempFileName is modified from WINE [ Alexandre Juiliard ]
* UPDATE HISTORY:
* Created 01/11/98
*/
-/* INCLUDES *****************************************************************/
+#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <ddk/ntddk.h>
#include <wstring.h>
#include <string.h>
-#include <kernel32/li.h>
+#include <ddk/li.h>
#include <ddk/rtl.h>
-#define NDEBUG
-#include <kernel32/kernel32.h>
-
-/* FUNCTIONS ****************************************************************/
-
HANDLE STDCALL CreateFileA(LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
WCHAR FileNameW[MAX_PATH];
ULONG i = 0;
- DPRINT("CreateFileA\n");
+ // OutputDebugStringA("CreateFileA\n");
while ((*lpFileName)!=0 && i < MAX_PATH)
{
}
+HANDLE STDCALL CreateFileW(LPCWSTR lpFileName,
+ DWORD dwDesiredAccess,
+ DWORD dwShareMode,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ DWORD dwCreationDisposition,
+ DWORD dwFlagsAndAttributes,
+ HANDLE hTemplateFile)
+{
+ HANDLE FileHandle;
+ NTSTATUS Status;
+
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING FileNameString;
+ ULONG Flags = 0;
+ WCHAR PathNameW[MAX_PATH];
+ WCHAR FileNameW[MAX_PATH];
+ WCHAR *FilePart;
+ UINT Len = 0;
+
+ if (!(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
+ {
+ Flags |= FILE_SYNCHRONOUS_IO_ALERT;
+ }
+
+// dprintf("CreateFile %S\n",lpFileName);
+
+ if ( lpFileName[0] == L'\\' || lpFileName[1] == L':') {
+ wcscpy(PathNameW,lpFileName);
+ }
+ else if ( ( ( dwCreationDisposition & OPEN_EXISTING ) == OPEN_EXISTING ) || ( ( dwCreationDisposition & TRUNCATE_EXISTING ) == TRUNCATE_EXISTING ) ) {
+ dprintf("Before SearchPath\n");
+ Len = SearchPathW(NULL,lpFileName,NULL,MAX_PATH,PathNameW,&FilePart);
+ if ( Len == 0 )
+ return NULL;
+ }
+ else {
+ Len = GetCurrentDirectoryW(MAX_PATH,PathNameW);
+ if ( Len == 0 )
+ return NULL;
+ if ( PathNameW[Len-1] != L'\\' ) {
+ PathNameW[Len] = L'\\';
+ PathNameW[Len+1] = 0;
+ }
+ wcscat(PathNameW,lpFileName);
+ }
+
+ if ( PathNameW[1] == L':' ) {
+ FileNameW[0] = '\\';
+ FileNameW[1] = '?';
+ FileNameW[2] = '?';
+ FileNameW[3] = '\\';
+ FileNameW[4] = 0;
+ wcscat(FileNameW,PathNameW);
+ }
+ else
+ wcscpy(FileNameW,PathNameW);
+
+
+
+ FileNameString.Length = wcslen( FileNameW)*sizeof(WCHAR);
+
+ if ( FileNameString.Length == 0 )
+ return NULL;
+
+ if ( FileNameString.Length > MAX_PATH*sizeof(WCHAR) )
+ return NULL;
+
+ FileNameString.Buffer = (WCHAR *)FileNameW;
+ FileNameString.MaximumLength = FileNameString.Length + sizeof(WCHAR);
+
+ ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+ ObjectAttributes.RootDirectory = NULL;
+ ObjectAttributes.ObjectName = &FileNameString;
+ ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
+ ObjectAttributes.SecurityDescriptor = NULL;
+ ObjectAttributes.SecurityQualityOfService = NULL;
+
+// dprintf("File Name %S\n",FileNameW);
+
+ Status = ZwCreateFile(&FileHandle,
+ dwDesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ dwFlagsAndAttributes,
+ dwShareMode,
+ dwCreationDisposition,
+ Flags,
+ NULL,
+ 0);
+
+ dprintf("After create file");
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return NULL;
+ }
+ return(FileHandle);
+}
+
+#if 0
HANDLE STDCALL CreateFileW(LPCWSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
UINT Len = 0;
WCHAR CurrentDir[MAX_PATH];
- DPRINT("CreateFileW\n");
+ OutputDebugStringA("CreateFileW\n");
if (!(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
{
PathNameW[3] = '\\';
PathNameW[4] = 0;
- DPRINT("Name %w\n",PathNameW);
+ dprintf("Name %w\n",PathNameW);
if (lpFileName[0] != L'\\' && lpFileName[1] != L':')
{
Len = GetCurrentDirectoryW(MAX_PATH,CurrentDir);
- DPRINT("CurrentDir %w\n",CurrentDir);
+ dprintf("CurrentDir %w\n",CurrentDir);
lstrcatW(PathNameW,CurrentDir);
- DPRINT("Name %w\n",PathNameW);
+ dprintf("Name %w\n",PathNameW);
}
lstrcatW(PathNameW,lpFileName);
- DPRINT("Name %w\n",PathNameW);
+ dprintf("Name %w\n",PathNameW);
FileNameString.Length = lstrlenW( PathNameW)*sizeof(WCHAR);
return NULL;
FileNameString.Buffer = (WCHAR *)PathNameW;
- FileNameString.MaximumLength = FileNameString.Length;
+ FileNameString.MaximumLength = FileNameString.Length+sizeof(WCHAR);
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
return(FileHandle);
}
+#endif
\ No newline at end of file
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/file/curdir.c
* PURPOSE: Current directory functions
+ * PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* Created 30/09/98
*/
#include <windows.h>
-#define NDEBUG
-#include <kernel32/kernel32.h>
-
/* GLOBALS *******************************************************************/
-static unsigned short CurrentDirectoryW[MAX_PATH] = {0,};
+WCHAR CurrentDirectoryW[MAX_PATH] = {0,};
-static unsigned short SystemDirectoryW[MAX_PATH];
+WCHAR SystemDirectoryW[MAX_PATH];
-static unsigned short WindowsDirectoryW[MAX_PATH];
+WCHAR WindowsDirectoryW[MAX_PATH];
/* FUNCTIONS *****************************************************************/
{
UINT uSize;
- DPRINT("CurrentDirectoryW %w\n",CurrentDirectoryW);
+ dprintf("CurrentDirectoryW %w\n",CurrentDirectoryW);
if ( lpBuffer == NULL )
return 0;
if ( nBufferLength > uSize )
lstrcpynW(lpBuffer,CurrentDirectoryW,uSize);
- DPRINT("GetCurrentDirectoryW() = %w\n",lpBuffer);
+ dprintf("GetCurrentDirectoryW() = %w\n",lpBuffer);
return uSize;
}
{
UINT i;
- DPRINT("SetCurrentDirectoryA(lpPathName %s)\n",lpPathName);
+ dprintf("SetCurrentDirectoryA(lpPathName %s)\n",lpPathName);
if ( lpPathName == NULL )
return FALSE;
}
CurrentDirectoryW[i] = 0;
- DPRINT("CurrentDirectoryW = '%w'\n",CurrentDirectoryW);
+ dprintf("CurrentDirectoryW = '%w'\n",CurrentDirectoryW);
return(TRUE);
}
-WINBOOL STDCALL SetCurrentDirectoryW(LPCWSTR lpPathName)
+WINBOOL
+STDCALL
+SetCurrentDirectoryW(
+ LPCWSTR lpPathName
+ )
{
if ( lpPathName == NULL )
return FALSE;
WCHAR NewDirectoryW[MAX_PATH];
ULONG i;
i = 0;
- if(lpTemplateDirectory)
- {
- while ((*lpTemplateDirectory)!=0 && i < MAX_PATH)
+ while ((*lpTemplateDirectory)!=0 && i < MAX_PATH)
{
TemplateDirectoryW[i] = *lpTemplateDirectory;
lpTemplateDirectory++;
i++;
}
- TemplateDirectoryW[i] = 0;
- }
+ TemplateDirectoryW[i] = 0;
i = 0;
while ((*lpNewDirectory)!=0 && i < MAX_PATH)
HANDLE DirectoryHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DirectoryNameString;
- WCHAR PathNameW[MAX_PATH],CurrentDir[MAX_PATH];
if ( lpTemplateDirectory != NULL ) {
// get object attributes from template directory
}
- PathNameW[0] = '\\';
- PathNameW[1] = '?';
- PathNameW[2] = '?';
- PathNameW[3] = '\\';
- PathNameW[4] = 0;
-
- if (lpNewDirectory[0] != L'\\' && lpNewDirectory[1] != L':')
- {
- GetCurrentDirectoryW(MAX_PATH,CurrentDir);
- lstrcatW(PathNameW,CurrentDir);
- }
- lstrcatW(PathNameW,lpNewDirectory);
- DirectoryNameString.Length = lstrlenW(PathNameW)*sizeof(WCHAR);
- DirectoryNameString.Buffer = (WCHAR *)PathNameW;
- DirectoryNameString.MaximumLength = DirectoryNameString.Length;
+ DirectoryNameString.Length = lstrlenW(lpNewDirectory)*sizeof(WCHAR);
+ DirectoryNameString.Buffer = (WCHAR *)lpNewDirectory;
+ DirectoryNameString.MaximumLength = DirectoryNameString.Length+sizeof(WCHAR);
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
ObjectAttributes.SecurityQualityOfService = NULL;
- errCode = NtCreateFile(&DirectoryHandle,
- FILE_LIST_DIRECTORY,
- &ObjectAttributes,
- NULL,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- FILE_CREATE,
- FILE_DIRECTORY_FILE,
- NULL,
- 0);
+ errCode = NtCreateDirectoryObject(
+ &DirectoryHandle,
+ GENERIC_ALL,
+ &ObjectAttributes
+ );
if (!NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
PathNameString.Length = lstrlenW(lpPathName)*sizeof(WCHAR);
PathNameString.Buffer = (WCHAR *)lpPathName;
- PathNameString.MaximumLength = PathNameString.Length;
+ PathNameString.MaximumLength = PathNameString.Length+sizeof(WCHAR);
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
}
+#define IS_END_OF_NAME(ch) (!(ch) || ((ch) == L'/') || ((ch) == L'\\'))
DWORD
LPWSTR *lpFilePart
)
{
+
+ WCHAR buffer[MAX_PATH];
+ WCHAR *p;
+
+ if (!lpFileName || !lpBuffer) return 0;
+
+ p = buffer;
+
+ if (IS_END_OF_NAME(*lpFileName) && (*lpFileName)) /* Absolute path */
+ {
+ while (*lpFileName == L'\\')
+ lpFileName++;
+ }
+ else /* Relative path or empty path */
+ {
+ if ( GetCurrentDirectoryW(MAX_PATH,p) == 0 )
+ wcscpy( p, L"C:");
+ if (*p)
+ p += wcslen(p);
+ }
+ if (!*lpFileName) /* empty path */
+ *p++ = '\\';
+ *p = '\0';
+
+ while (*lpFileName)
+ {
+ if (*lpFileName == '.')
+ {
+ if (IS_END_OF_NAME(lpFileName[1]))
+ {
+ lpFileName++;
+ while (*lpFileName == L'\\' ) lpFileName++;
+ continue;
+ }
+ else if ((lpFileName[1] == L'.') && IS_END_OF_NAME(lpFileName[2]))
+ {
+ lpFileName += 2;
+ while ((*lpFileName == '\\') ) lpFileName++;
+ while ((p > buffer + 2) && (*p != '\\')) p--;
+ *p = '\0'; /* Remove trailing separator */
+ continue;
+ }
+ }
+ if (p >= buffer + sizeof(buffer) - 1)
+ {
+ //DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk);
+ return 0;
+ }
+ *p++ = '\\';
+ while (!IS_END_OF_NAME(*lpFileName) && (p < buffer + sizeof(buffer) -1))
+ *p++ = *lpFileName++;
+ *p = '\0';
+ while ((*lpFileName == '\\') ) lpFileName++;
+ }
+
+ if (!buffer[2])
+ {
+ buffer[2] = '\\';
+ buffer[3] = '\0';
+ }
+
+
+ wcsncpy( lpBuffer, buffer, nBufferLength);
+
+ //TRACE(dosfs, "returning %s\n", buffer );
+ return wcslen(buffer);
}
+
+
+
+
+
+
+
DWORD
STDCALL
GetShortPathNameA(
LPSTR *lpFilePart
)
{
+ WCHAR PathW[MAX_PATH];
+ WCHAR FileNameW[MAX_PATH];
+ WCHAR ExtensionW[MAX_PATH];
+
+ WCHAR BufferW[MAX_PATH];
+ WCHAR *FilePartW;
+
+ ULONG i;
+ DWORD RetValue;
+
+ i = 0;
+ while ((*lpPath)!=0 && i < MAX_PATH)
+ {
+ PathW[i] = *lpPath;
+ lpPath++;
+ i++;
+ }
+ PathW[i] = 0;
+
+ i = 0;
+ while ((*lpFileName)!=0 && i < MAX_PATH)
+ {
+ FileNameW[i] = *lpFileName;
+ lpFileName++;
+ i++;
+ }
+ FileNameW[i] = 0;
+
+ i = 0;
+ while ((*lpExtension)!=0 && i < MAX_PATH)
+ {
+ ExtensionW[i] = *lpExtension;
+ lpExtension++;
+ i++;
+ }
+ ExtensionW[i] = 0;
+
+ RetValue = SearchPathW(PathW,FileNameW,ExtensionW,nBufferLength,BufferW,&FilePartW);
+ for(i=0;i<nBufferLength;i++)
+ lpBuffer[i] = (char)BufferW[i];
+
+ lpFilePart = strrchr(lpBuffer,'\\')+1;
+ return RetValue;
}
DWORD
)
{
- //1. The directory from which the application loaded.
- //2. The current directory.
- //3. Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.
- //4. Windows NT only: The 16-bit Windows system directory. There is no Win32 function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
- //5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- //6. The directories that are listed in the PATH environment variable.
+
NTSTATUS errCode;
DWORD retCode = 0;
HANDLE FileHandle = NULL;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
+ dprintf("SearchPath\n");
-
-
-
+
if ( lpPath == NULL ) {
-
+
// check the directory from which the application loaded
if ( GetCurrentDirectoryW( MAX_PATH, BufferW ) > 0 ) {
if ( lpExtension != NULL ) {
if ( lpFileName[i-4] != L'.' ) {
- memcpy(FileAndExtensionW,lpFileName,(i+1)*sizeof(WCHAR));
- lstrcatW(FileAndExtensionW,lpExtension);
+ wcscpy(FileAndExtensionW,lpFileName);
+ wcscat(FileAndExtensionW,lpExtension);
}
else
- memcpy(FileAndExtensionW,lpFileName,(i+1)*sizeof(WCHAR));
+ wcscpy(FileAndExtensionW,lpFileName);
}
else
- memcpy(FileAndExtensionW,lpFileName,(i+1)*sizeof(WCHAR));
+ wcscpy(FileAndExtensionW,lpFileName);
- if ( lpPath[0] == L'\\' )
- lstrcatW(lpBuffer,lpPath);
- else {
- lstrcatW(lpBuffer,L"\\??\\");
- lstrcatW(lpBuffer,lpPath);
- }
+
+ lstrcatW(BufferW,L"\\??\\");
+ lstrcatW(BufferW,lpPath);
+
//printf("%S\n",FileAndExtensionW);
- i = lstrlenW(lpBuffer);
- if ( lpBuffer[i-1] != L'\\' ) {
- lpBuffer[i] = L'\\';
- lpBuffer[i+1] = 0;
+ i = wcslen(BufferW);
+ if ( BufferW[i-1] != L'\\' ) {
+ BufferW[i] = L'\\';
+ BufferW[i+1] = 0;
}
if ( lpFilePart != NULL )
- *lpFilePart = &lpBuffer[lstrlenW(lpBuffer)+1];
- lstrcatW(lpBuffer,FileAndExtensionW);
+ *lpFilePart = &BufferW[wcslen(BufferW)+1];
+ wcscat(BufferW,FileAndExtensionW);
//printf("%S\n",lpBuffer);
- PathString.Buffer = lpBuffer;
+ PathString.Buffer = BufferW;
PathString.Length = lstrlenW(PathString.Buffer)*sizeof(WCHAR);
- PathString.MaximumLength = PathString.Length;
+ PathString.MaximumLength = PathString.Length + sizeof(WCHAR);
if ( !NT_SUCCESS(errCode) ) {
return 0;
}
-
+ else {
+ NtClose(FileHandle);
+ wcscpy(lpBuffer,&BufferW[4]);
+ lpFilePart = wcsrchr(lpBuffer,'\\')+1;
+ }
}
return lstrlenW(lpBuffer);
}
+
#include <ddk/ntddk.h>
#include <wstring.h>
#include <string.h>
-#include <kernel32/li.h>
+#include <ddk/li.h>
#include <ddk/rtl.h>
#define LPPROGRESS_ROUTINE void*
LPOVERLAPPED lpOverLapped)
{
- PLARGE_INTEGER Offset;
- LARGE_INTEGER ByteOffset;
+ LARGE_INTEGER Offset;
HANDLE hEvent = NULL;
NTSTATUS errCode;
- PIO_STATUS_BLOCK IoStatusBlock;
- IO_STATUS_BLOCK IIosb;
- if ( lpOverLapped != NULL )
+
+ WCHAR Buffer[1000];
+
+ //printk("%.*s",nNumberOfBytesToWrite,lpBuffer);
+
+ if (lpOverLapped != NULL )
{
- SET_LARGE_INTEGER_LOW_PART(ByteOffset, lpOverLapped->Offset);
- SET_LARGE_INTEGER_HIGH_PART(ByteOffset, lpOverLapped->OffsetHigh);
- Offset = &ByteOffset;
+ SET_LARGE_INTEGER_LOW_PART(Offset, lpOverLapped->Offset);
+ SET_LARGE_INTEGER_HIGH_PART(Offset, lpOverLapped->OffsetHigh);
lpOverLapped->Internal = STATUS_PENDING;
- hEvent = lpOverLapped->hEvent;
- IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
- }
- else
- {
- IoStatusBlock = &IIosb;
- Offset = NULL;
+ hEvent= lpOverLapped->hEvent;
}
errCode = NtWriteFile(hFile,hEvent,NULL,NULL,
(PIO_STATUS_BLOCK)lpOverLapped,
(PVOID)lpBuffer,
nNumberOfBytesToWrite,
- Offset,
+ &Offset,
NULL);
if (!NT_SUCCESS(errCode))
{
PIO_STATUS_BLOCK IoStatusBlock;
IO_STATUS_BLOCK IIosb;
-
+
if ( lpOverLapped != NULL )
{
SET_LARGE_INTEGER_LOW_PART(ByteOffset, lpOverLapped->Offset);
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
+
+
return TRUE;
}
FileNameString.Length = lstrlenW(PathNameW)*sizeof(WCHAR);
FileNameString.Buffer = PathNameW;
- FileNameString.MaximumLength = FileNameString.Length;
+ FileNameString.MaximumLength = FileNameString.Length+sizeof(WCHAR);
NTSTATUS errCode;
WCHAR PathNameW[MAX_PATH];
UINT Len;
-
- Len = GetCurrentDirectoryW(MAX_PATH,PathNameW);
- if ( Len == 0 )
- return FALSE;
- if ( PathNameW[Len-1] != L'\\' ) {
- PathNameW[Len] = L'\\';
- PathNameW[Len+1] = 0;
+ if ( lpFileName[1] != ':' ) {
+ Len = GetCurrentDirectoryW(MAX_PATH,PathNameW);
+ if ( Len == 0 )
+ return FALSE;
+ if ( PathNameW[Len-1] != L'\\' ) {
+ PathNameW[Len] = L'\\';
+ PathNameW[Len+1] = 0;
+ }
}
+ else
+ PathNameW[0] = 0;
lstrcatW(PathNameW,lpFileName);
FileNameString.Length = lstrlenW( PathNameW)*sizeof(WCHAR);
if ( FileNameString.Length == 0 )
return FALSE;
- if ( FileNameString.Length > MAX_PATH )
+ if ( FileNameString.Length > MAX_PATH*sizeof(WCHAR) )
return FALSE;
FileNameString.Buffer = (WCHAR *)PathNameW;
- FileNameString.MaximumLength = FileNameString.Length;
+ FileNameString.MaximumLength = FileNameString.Length+sizeof(WCHAR);
}
+WINBOOL
+STDCALL
+SetFileAttributesA(
+ LPCSTR lpFileName,
+ DWORD dwFileAttributes
+ )
+{
+ ULONG i;
+ WCHAR FileNameW[MAX_PATH];
+ i = 0;
+ while ((*lpFileName)!=0 && i < MAX_PATH)
+ {
+ FileNameW[i] = *lpFileName;
+ lpFileName++;
+ i++;
+ }
+ FileNameW[i] = 0;
+ return SetFileAttributesW(FileNameW, dwFileAttributes);
+}
+
+
+WINBOOL
+STDCALL
+SetFileAttributesW(
+ LPCWSTR lpFileName,
+ DWORD dwFileAttributes
+ )
+{
+ IO_STATUS_BLOCK IoStatusBlock;
+ FILE_BASIC_INFORMATION FileBasic;
+ HANDLE hFile;
+ NTSTATUS errCode;
+
+
+ hFile = CreateFileW(
+ lpFileName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+
+
+ errCode = NtQueryInformationFile(hFile,&IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION),FileBasicInformation);
+ if ( !NT_SUCCESS(errCode) ) {
+ CloseHandle(hFile);
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ FileBasic.FileAttributes = dwFileAttributes;
+ errCode = NtSetInformationFile(hFile,&IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION),FileBasicInformation);
+ if ( !NT_SUCCESS(errCode) ) {
+ CloseHandle(hFile);
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ CloseHandle(hFile);
+ return TRUE;
+
+}
+
DWORD
{
NTSTATUS errCode;
FILETIME CurrentTime;
- errCode = NtQuerySystemTime (
- (TIME *)&CurrentTime
- );
+memset(&CurrentTime,sizeof(FILETIME),0);
+// errCode = NtQuerySystemTime (
+// (TIME *)&CurrentTime
+// );
return CurrentTime.dwLowDateTime;
}
if (uUnique == 0)
uUnique = GetCurrentTime();
-
- wsprintfA(lpTempFileName,"%s\\%c%.3s%4.4x%s",
+ /*
+ sprintf(lpTempFileName,"%s\\%c%.3s%4.4x%s",
lpPathName,'~',lpPrefixString,uUnique,".tmp");
-
+ */
if (unique)
return uUnique;
CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
0)) == INVALID_HANDLE_VALUE)
{
- wsprintfA(lpTempFileName,"%s\\%c%.3s%4.4x%s",
- lpPathName,'~',lpPrefixString,++uUnique,".tmp");
+ // wsprintfA(lpTempFileName,"%s\\%c%.3s%4.4x%s",
+// lpPathName,'~',lpPrefixString,++uUnique,".tmp");
}
CloseHandle((HANDLE)hFile);
if (uUnique == 0)
uUnique = GetCurrentTime();
- wsprintfW(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
- lpPathName,'~',lpPrefixString,uUnique,L".tmp");
+ // swprintf(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
+// lpPathName,'~',lpPrefixString,uUnique,L".tmp");
if (unique)
return uUnique;
CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
0)) == INVALID_HANDLE_VALUE)
{
- wsprintfW(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
- lpPathName,'~',lpPrefixString,++uUnique,L".tmp");
+// wsprintfW(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
+// lpPathName,'~',lpPrefixString,++uUnique,L".tmp");
}
CloseHandle((HANDLE)hFile);
return TRUE;
}
+
+WINBOOL
+STDCALL
+SetEndOfFile(
+ HANDLE hFile
+ )
+{
+ int x = -1;
+ DWORD Num;
+ return WriteFile(hFile,&x,1,&Num,NULL);
+}
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS system libraries\r
- * FILE: lib/kernel32/file/find.c\r
- * PURPOSE: Find functions\r
- * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)\r
- * UPDATE HISTORY:\r
- * Created 01/11/98\r
- */\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include <windows.h>\r
-#include <wstring.h>\r
-#include <ddk/ntddk.h>\r
-\r
-#define NDEBUG\r
-#include <kernel32/kernel32.h>\r
-\r
-/* TYPES ********************************************************************/\r
-\r
-typedef struct _KERNEL32_FIND_FILE_DATA\r
-{\r
- HANDLE DirectoryHandle;\r
- FILE_DIRECTORY_INFORMATION FileInfo;\r
- WCHAR FileNameExtra[MAX_PATH];\r
- UNICODE_STRING PatternStr;\r
-} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;\r
-\r
-typedef struct _WIN32_FIND_DATA_UNICODE {\r
- DWORD dwFileAttributes; \r
- FILETIME ftCreationTime; \r
- FILETIME ftLastAccessTime; \r
- FILETIME ftLastWriteTime; \r
- DWORD nFileSizeHigh; \r
- DWORD nFileSizeLow; \r
- DWORD dwReserved0; \r
- DWORD dwReserved1; \r
- WCHAR cFileName[ MAX_PATH ]; \r
- WCHAR cAlternateFileName[ 14 ]; \r
-} WIN32_FIND_DATA_UNICODE, *PWIN32_FIND_DATA_UNICODE; \r
-\r
-typedef struct _WIN32_FIND_DATA_ASCII { \r
- DWORD dwFileAttributes; \r
- FILETIME ftCreationTime; \r
- FILETIME ftLastAccessTime; \r
- FILETIME ftLastWriteTime; \r
- DWORD nFileSizeHigh; \r
- DWORD nFileSizeLow; \r
- DWORD dwReserved0; \r
- DWORD dwReserved1; \r
- CHAR cFileName[ MAX_PATH ]; \r
- CHAR cAlternateFileName[ 14 ]; \r
-} WIN32_FIND_DATA_ASCII, *PWIN32_FIND_DATA_ASCII; \r
-\r
-\r
-/* FUNCTIONS *****************************************************************/\r
-\r
-WINBOOL STDCALL InternalFindNextFile(HANDLE hFindFile,\r
- LPWIN32_FIND_DATA lpFindFileData)\r
-{\r
- IO_STATUS_BLOCK IoStatusBlock;\r
- NTSTATUS Status;\r
- PKERNEL32_FIND_FILE_DATA IData;\r
- \r
- IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;\r
- \r
- Status = NtQueryDirectoryFile(IData->DirectoryHandle,\r
- NULL,\r
- NULL,\r
- NULL,\r
- &IoStatusBlock,\r
- (PVOID)&IData->FileInfo,\r
- sizeof(IData->FileInfo) +\r
- sizeof(IData->FileNameExtra),\r
- FileDirectoryInformation,\r
- TRUE,\r
- &(IData->PatternStr),\r
- FALSE);\r
- DPRINT("Found %w\n",IData->FileInfo.FileName);\r
- lpFindFileData->dwFileAttributes = IData->FileInfo.FileAttributes;\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(FALSE);\r
- }\r
- return(TRUE);\r
-}\r
-\r
-HANDLE STDCALL InternalFindFirstFile(LPCWSTR lpFileName, \r
- LPWIN32_FIND_DATA lpFindFileData)\r
-{\r
- WCHAR CurrentDirectory[MAX_PATH];\r
- WCHAR Pattern[MAX_PATH];\r
- WCHAR Directory[MAX_PATH];\r
- PWSTR End;\r
- PKERNEL32_FIND_FILE_DATA IData;\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- UNICODE_STRING DirectoryNameStr;\r
- IO_STATUS_BLOCK IoStatusBlock;\r
- \r
- DPRINT("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",\r
- lpFileName, lpFindFileData);\r
- \r
- GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);\r
- Directory[0] = '\\';\r
- Directory[1] = '?';\r
- Directory[2] = '?';\r
- Directory[3] = '\\';\r
- Directory[4] = 0;\r
- DPRINT("Directory %w\n",Directory);\r
- wcscat(Directory, CurrentDirectory);\r
- DPRINT("Directory %w\n",Directory);\r
- wcscat(Directory, lpFileName);\r
- DPRINT("Directory %w\n",Directory);\r
- End = wcsrchr(Directory, '\\');\r
- *End = 0;\r
- \r
- wcscpy(Pattern, End+1);\r
- \r
- DPRINT("Directory %w Pattern %w\n",Directory,Pattern);\r
- \r
- IData = HeapAlloc(GetProcessHeap(), \r
- HEAP_ZERO_MEMORY, \r
- sizeof(KERNEL32_FIND_FILE_DATA));\r
- \r
- RtlInitUnicodeString(&DirectoryNameStr, Directory);\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &DirectoryNameStr,\r
- 0,\r
- NULL,\r
- NULL);\r
- \r
- if (ZwOpenFile(&IData->DirectoryHandle,\r
- FILE_LIST_DIRECTORY,\r
- &ObjectAttributes,\r
- &IoStatusBlock,\r
- 0,\r
- OPEN_EXISTING)!=STATUS_SUCCESS)\r
- {\r
- return(NULL);\r
- }\r
- \r
- RtlInitUnicodeString(&(IData->PatternStr), Pattern);\r
- \r
- NtQueryDirectoryFile(IData->DirectoryHandle,\r
- NULL,\r
- NULL,\r
- NULL,\r
- &IoStatusBlock,\r
- (PVOID)&IData->FileInfo,\r
- sizeof(IData->FileInfo) +\r
- sizeof(IData->FileNameExtra),\r
- FileDirectoryInformation,\r
- TRUE,\r
- &(IData->PatternStr),\r
- FALSE);\r
- DPRINT("Found %w\n",IData->FileInfo.FileName);\r
- \r
- lpFindFileData->dwFileAttributes = IData->FileInfo.FileAttributes;\r
- return(IData);\r
-}\r
-\r
-HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)\r
-{\r
- WCHAR lpFileNameW[MAX_PATH];\r
- ULONG i;\r
- PKERNEL32_FIND_FILE_DATA IData;\r
- PWIN32_FIND_DATA_ASCII Ret;\r
-\r
- i = 0;\r
- while (lpFileName[i]!=0)\r
- {\r
- lpFileNameW[i] = lpFileName[i];\r
- i++;\r
- }\r
- lpFileNameW[i] = 0;\r
- \r
- IData = InternalFindFirstFile(lpFileNameW,lpFindFileData);\r
- Ret = (PWIN32_FIND_DATA_ASCII)lpFindFileData;\r
-\r
- for (i=0; i<IData->FileInfo.FileNameLength; i++)\r
- {\r
- Ret->cFileName[i] = IData->FileInfo.FileName[i];\r
- }\r
- Ret->cFileName[i] = 0;\r
- \r
- return(IData);\r
-}\r
-\r
-WINBOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)\r
-{\r
- PWIN32_FIND_DATA_ASCII Ret;\r
- PKERNEL32_FIND_FILE_DATA IData;\r
- ULONG i;\r
-\r
- IData = (PKERNEL32_FIND_FILE_DATA)hFindFile; \r
- if (!InternalFindNextFile(hFindFile, lpFindFileData))\r
- {\r
- return(FALSE);\r
- }\r
-\r
- Ret = (PWIN32_FIND_DATA_ASCII)lpFindFileData;\r
-\r
- for (i=0; i<IData->FileInfo.FileNameLength; i++)\r
- {\r
- Ret->cFileName[i] = IData->FileInfo.FileName[i];\r
- }\r
- Ret->cFileName[i] = 0;\r
- \r
- return(TRUE);\r
-}\r
-\r
-BOOL FindClose(HANDLE hFindFile)\r
-{\r
- PKERNEL32_FIND_FILE_DATA IData;\r
- \r
- IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;\r
- NtClose(IData->DirectoryHandle);\r
- HeapFree(GetProcessHeap(), 0, IData);\r
- return(TRUE);\r
-}\r
-\r
-HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName, \r
- LPWIN32_FIND_DATA lpFindFileData)\r
-{\r
- PWIN32_FIND_DATA_UNICODE Ret;\r
- PKERNEL32_FIND_FILE_DATA IData;\r
- \r
- IData = InternalFindFirstFile(lpFileName,lpFindFileData);\r
- Ret = (PWIN32_FIND_DATA_UNICODE)lpFindFileData;\r
-\r
- memcpy(Ret->cFileName, IData->FileInfo.FileName, \r
- IData->FileInfo.FileNameLength);\r
- memset(Ret->cAlternateFileName, 0, 14);\r
-\r
- return(IData);\r
-}\r
-\r
-WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,\r
- LPWIN32_FIND_DATA lpFindFileData)\r
-{\r
- PWIN32_FIND_DATA_UNICODE Ret;\r
- PKERNEL32_FIND_FILE_DATA IData;\r
-\r
- IData = (PKERNEL32_FIND_FILE_DATA)hFindFile; \r
- if (!InternalFindNextFile(hFindFile, lpFindFileData))\r
- {\r
- return(FALSE);\r
- }\r
-\r
- Ret = (PWIN32_FIND_DATA_UNICODE)lpFindFileData;\r
-\r
- memcpy(Ret->cFileName, IData->FileInfo.FileName, \r
- IData->FileInfo.FileNameLength);\r
- memset(Ret->cAlternateFileName, 0, 14);\r
-\r
- return(TRUE);\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/kernel32/file/find.c
+ * PURPOSE: Find functions
+ * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
+ * UPDATE HISTORY:
+ * Created 01/11/98
+ */
+#include <windows.h>
+#include <wstring.h>
+#include <string.h>
+#include <ddk/ntddk.h>
+
+
+
+
+
+
+
+
+typedef struct _FIND_FILE_INFO
+{
+ ULONG Offset;
+ WCHAR PathName[MAX_PATH];
+ WCHAR FileName[MAX_PATH];
+ FILE_DIRECTORY_INFORMATION *FileDirectory;
+} FIND_FILE_INFO;
+
+typedef struct _NOTIFY_INFO
+{
+ HANDLE Event;
+ HANDLE FileHandle;
+ DWORD dwNotifyFilter;
+ WINBOOL bWatchSubtree;
+} NOTIFY_INFO;
+
+
+
+
+typedef struct _WIN32_FIND_DATAW {
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+ DWORD dwReserved0;
+ DWORD dwReserved1;
+ WCHAR cFileName[ MAX_PATH ];
+ WCHAR cAlternateFileName[ 14 ];
+} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW, *PWIN32_FIND_DATAW;
+
+
+WINBOOL
+STDCALL
+FindClose(
+ HANDLE hFind
+ )
+{
+
+ if ( hFind == NULL)
+ return FALSE;
+ if ( hFind == (HANDLE)-1)
+ return FALSE;
+
+ HeapFree(GetProcessHeap(),0,((FIND_FILE_INFO *)hFind)->FileDirectory);
+ HeapFree(GetProcessHeap(),0,hFind);
+ return TRUE;
+}
+
+
+
+HANDLE
+STDCALL
+FindFirstFileA(
+ LPCSTR lpFileName,
+ LPWIN32_FIND_DATA lpFindFileData
+ )
+{
+ WIN32_FIND_DATAW FindFileDataW;
+ WCHAR FileNameW[MAX_PATH];
+ ULONG i;
+ HANDLE hFind;
+
+ i = 0;
+ while ((*lpFileName)!=0 && i < MAX_PATH)
+ {
+ FileNameW[i] = *lpFileName;
+ lpFileName++;
+ i++;
+ }
+ FileNameW[i] = 0;
+ hFind = FindFirstFileW(FileNameW,(WIN32_FIND_DATA *)&FindFileDataW);
+
+ lpFindFileData->dwFileAttributes = FindFileDataW.dwFileAttributes;
+ memcpy(&lpFindFileData->ftCreationTime,&FindFileDataW.ftCreationTime,sizeof(FILETIME));
+ memcpy(&lpFindFileData->ftLastAccessTime,&FindFileDataW.ftLastAccessTime,sizeof(FILETIME));
+ memcpy(&lpFindFileData->ftLastWriteTime,&FindFileDataW.ftLastWriteTime,sizeof(FILETIME));
+ lpFindFileData->nFileSizeHigh = FindFileDataW.nFileSizeHigh;
+ lpFindFileData->nFileSizeLow = FindFileDataW.nFileSizeLow;
+ lpFindFileData->dwReserved0= FindFileDataW.dwReserved0;
+ lpFindFileData->dwReserved1= FindFileDataW.dwReserved1;
+ i = 0;
+ while ((lpFindFileData->cFileName[i])!=0 && i < MAX_PATH)
+ {
+ lpFindFileData->cFileName[i] = (char)FindFileDataW.cFileName[i];
+ i++;
+ }
+ lpFindFileData->cFileName[i] = 0;
+
+ i = 0;
+ while ((lpFindFileData->cAlternateFileName[i])!=0 && i < 14)
+ {
+ lpFindFileData->cAlternateFileName[i] = (char)FindFileDataW.cAlternateFileName[i];
+ i++;
+ }
+ lpFindFileData->cAlternateFileName[i] = 0;
+
+
+ return hFind;
+}
+
+HANDLE
+STDCALL
+FindFirstFileW(
+ LPCWSTR lpFileName,
+ LPWIN32_FIND_DATA lpFindFileData
+ )
+{
+ NTSTATUS errCode;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE FileHandle = NULL;
+ FIND_FILE_INFO *hFind;
+ WCHAR *FilePart;
+ UNICODE_STRING FileNameString, PathNameString;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+
+
+ ACCESS_MASK DesiredAccess=FILE_READ_DATA;
+
+ ULONG FileAttributes=FILE_ATTRIBUTE_DIRECTORY;
+ ULONG ShareAccess=FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ ULONG CreateDisposition=FILE_OPEN;
+ ULONG CreateOptions=FILE_DIRECTORY_FILE;
+
+
+ hFind = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,sizeof(FIND_FILE_INFO));
+
+ hFind->FileDirectory = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,8192);
+
+
+
+ /* Try to find a path and a filename in the passed filename */
+
+ lstrcpyW(hFind->PathName, lpFileName);
+ FilePart = wcsrchr(hFind->PathName, '\\');
+
+ if (FilePart == NULL){
+ GetCurrentDirectoryW(MAX_PATH, hFind->PathName);
+ lstrcpyW(hFind->FileName, lpFileName);
+ }
+ else {
+ lstrcpyW(hFind->FileName, &FilePart[1]);
+ }
+
+ hFind->Offset = 0;
+
+
+ PathNameString.Length = lstrlenW(hFind->PathName)*sizeof(WCHAR);
+ PathNameString.Buffer = hFind->PathName;
+ PathNameString.MaximumLength = FileNameString.Length+sizeof(WCHAR);
+
+
+ FileNameString.Length = lstrlenW(hFind->FileName)*sizeof(WCHAR);
+ FileNameString.Buffer = hFind->FileName;
+ FileNameString.MaximumLength = FileNameString.Length+sizeof(WCHAR);
+
+
+ ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+ ObjectAttributes.RootDirectory = NULL;
+ ObjectAttributes.ObjectName = &PathNameString;
+ ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
+ ObjectAttributes.SecurityDescriptor = NULL;
+ ObjectAttributes.SecurityQualityOfService = NULL;
+
+
+
+
+
+
+ errCode = NtCreateFile(
+ &FileHandle,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FileAttributes,
+ ShareAccess,
+ CreateDisposition,
+ CreateOptions,
+ NULL,
+ 0); //
+
+ if ( !NT_SUCCESS(errCode) ) {
+
+ return NULL;
+ }
+
+ errCode = NtQueryDirectoryFile(
+ FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ hFind->FileDirectory,
+ 8192,
+ FileDirectoryInformation,
+ FALSE,
+ &FileNameString,
+ FALSE
+ );
+ if ( !NT_SUCCESS(errCode) ) {
+ // printf("%x\n",errCode);
+ return NULL;
+ }
+
+
+
+
+ if ( FindNextFileW(hFind,lpFindFileData) )
+ return hFind;
+ else {
+ FindClose(hFind);
+ return NULL;
+ }
+ return NULL;
+}
+
+WINBOOL
+STDCALL
+FindNextFileA(
+ HANDLE hFind,
+ LPWIN32_FIND_DATA lpFindFileData
+ )
+{
+ WIN32_FIND_DATAW FindFileDataW;
+ ULONG i;
+
+
+ hFind = FindNextFileW(hFind,(WIN32_FIND_DATA *)&FindFileDataW);
+
+ lpFindFileData->dwFileAttributes = FindFileDataW.dwFileAttributes;
+ memcpy(&lpFindFileData->ftCreationTime,&FindFileDataW.ftCreationTime,sizeof(FILETIME));
+ memcpy(&lpFindFileData->ftLastAccessTime,&FindFileDataW.ftLastAccessTime,sizeof(FILETIME));
+ memcpy(&lpFindFileData->ftLastWriteTime,&FindFileDataW.ftLastWriteTime,sizeof(FILETIME));
+ lpFindFileData->nFileSizeHigh = FindFileDataW.nFileSizeHigh;
+ lpFindFileData->nFileSizeLow = FindFileDataW.nFileSizeLow;
+ lpFindFileData->dwReserved0= FindFileDataW.dwReserved0;
+ lpFindFileData->dwReserved1= FindFileDataW.dwReserved1;
+ i = 0;
+ while ((lpFindFileData->cFileName[i])!=0 && i < MAX_PATH)
+ {
+ lpFindFileData->cFileName[i] = (char)FindFileDataW.cFileName[i];
+ i++;
+ }
+ lpFindFileData->cFileName[i] = 0;
+
+ i = 0;
+ while ((lpFindFileData->cAlternateFileName[i])!=0 && i < 14)
+ {
+ lpFindFileData->cAlternateFileName[i] = (char)FindFileDataW.cAlternateFileName[i];
+ i++;
+ }
+ lpFindFileData->cAlternateFileName[i] = 0;
+
+
+ return hFind;
+}
+
+WINBOOL
+STDCALL
+FindNextFileW(
+ HANDLE hFind,
+ LPWIN32_FIND_DATA lpFindFileData
+ )
+{
+
+
+ LPWIN32_FIND_DATAW lpFindFileDataW = (LPWIN32_FIND_DATAW)lpFindFileData;
+
+ FIND_FILE_INFO *FindPtr = hFind;
+ FILE_DIRECTORY_INFORMATION *FileDirectory=NULL;
+
+ if ( FindPtr == NULL )
+ return FALSE;
+ if ( FileDirectory->NextEntryOffset == 0 )
+ return FALSE;
+
+ /* Try to find a file */
+ FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
+
+
+
+
+ FindPtr->Offset += FileDirectory->NextEntryOffset;
+
+ /* We found one! */
+ if (FindPtr->PathName[0] != L'\0')
+ {
+ wcscpy(lpFindFileDataW->cFileName, FindPtr->PathName);
+ wcscat(lpFindFileDataW->cFileName, L"\\");
+ wcscat(lpFindFileDataW->cFileName, FileDirectory->FileName);
+ }
+ else
+ wcscpy(lpFindFileDataW->cFileName, FileDirectory->FileName);
+
+
+
+ wcscpy(lpFindFileDataW->cAlternateFileName, L"");
+ lpFindFileData->dwReserved0 = 0;
+ lpFindFileData->dwReserved1 = 0;
+ return TRUE;
+
+}
+
+
+
+
+
+
+HANDLE
+STDCALL
+FindFirstChangeNotificationA(
+ LPCSTR lpPathName,
+ WINBOOL bWatchSubtree,
+ DWORD dwNotifyFilter
+ )
+{
+ ULONG i;
+
+ WCHAR PathNameW[MAX_PATH];
+
+
+
+
+ i = 0;
+ while ((*lpPathName)!=0 && i < MAX_PATH)
+ {
+ PathNameW[i] = *lpPathName;
+ lpPathName++;
+ i++;
+ }
+ PathNameW[i] = 0;
+ return FindFirstChangeNotificationW(PathNameW, bWatchSubtree, dwNotifyFilter );
+
+}
+
+HANDLE
+STDCALL
+FindFirstChangeNotificationW(
+ LPCWSTR lpPathName,
+ WINBOOL bWatchSubtree,
+ DWORD dwNotifyFilter
+ )
+{
+ NTSTATUS errCode;
+
+
+ IO_STATUS_BLOCK IoStatusBlock;
+ NOTIFY_INFO *NotifyHandle;
+ WCHAR Buffer[100];
+ ULONG BufferSize = 100;
+
+ NotifyHandle = HeapAlloc(GetProcessHeap(),0,sizeof(NOTIFY_INFO));
+
+ NotifyHandle->Event = CreateEventW(NULL,FALSE,FALSE,NULL);
+ NotifyHandle->FileHandle = CreateFileW(lpPathName,GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+
+ NotifyHandle->dwNotifyFilter = dwNotifyFilter;
+ NotifyHandle->bWatchSubtree = bWatchSubtree;
+
+ errCode = NtNotifyChangeDirectoryFile(
+ NotifyHandle->FileHandle,
+ NotifyHandle->Event,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ Buffer,
+ BufferSize,
+ NotifyHandle->dwNotifyFilter,
+ NotifyHandle->bWatchSubtree
+ );
+ return NotifyHandle;
+}
+
+WINBOOL
+STDCALL
+FindNextChangeNotification(
+ HANDLE hChangeHandle
+ )
+{
+ NTSTATUS errCode;
+
+
+ IO_STATUS_BLOCK IoStatusBlock;
+ NOTIFY_INFO *NotifyHandle = hChangeHandle;
+
+ WCHAR Buffer[100];
+ ULONG BufferSize = 100;
+ EVENT_BASIC_INFORMATION EventBasic;
+ ULONG ReturnLength;
+
+
+
+ NtQueryEvent(NotifyHandle->Event,EventBasicInformation,&EventBasic,sizeof(EVENT_BASIC_INFORMATION),&ReturnLength);
+
+ if ( EventBasic.Signaled == TRUE ) {
+ ResetEvent(NotifyHandle->Event);
+ return TRUE;
+ }
+
+ errCode = NtNotifyChangeDirectoryFile(
+ NotifyHandle->FileHandle,
+ NotifyHandle->Event,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ Buffer,
+ BufferSize,
+ NotifyHandle->dwNotifyFilter,
+ (BOOLEAN)NotifyHandle->bWatchSubtree
+ );
+
+ return FALSE;
+}
+
+WINBOOL
+STDCALL
+FindCloseChangeNotification(
+ HANDLE hChangeHandle
+ )
+{
+ HeapFree(GetProcessHeap(),0,hChangeHandle);
+ return TRUE;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
+WINBOOL
+STDCALL
+SetVolumeLabelA(
+ LPCSTR lpRootPathName,
+ LPCSTR lpVolumeName
+ )
+{
+ WCHAR RootPathNameW[MAX_PATH];
+ WCHAR VolumeNameW[MAX_PATH];
+ UINT i;
+
+ i = 0;
+ while ((*lpRootPathName)!=0 && i < MAX_PATH)
+ {
+ RootPathNameW[i] = *lpRootPathName;
+ lpRootPathName++;
+ i++;
+ }
+ RootPathNameW[i] = 0;
+
+ i = 0;
+ while ((*lpVolumeName)!=0 && i < MAX_PATH)
+ {
+ VolumeNameW[i] = *lpVolumeName;
+ lpVolumeName++;
+ i++;
+ }
+ VolumeNameW[i] = 0;
+ return SetVolumeLabelW(RootPathNameW,VolumeNameW);
+}
+
+WINBOOL
+STDCALL
+SetVolumeLabelW(
+ LPCWSTR lpRootPathName,
+ LPCWSTR lpVolumeName
+ )
+{
+ return FALSE;
+}
SYNCH_OBJECTS = synch/critical.o synch/event.o synch/wait.o
-MISC_OBJECTS = misc/error.o misc/atom.o misc/handle.o misc/env.o misc/dllmain.o
+MISC_OBJECTS = misc/error.o misc/atom.o misc/handle.o misc/env.o misc/dllmain.o \
+ misc/console.o
FILE_OBJECTS = file/file.o file/curdir.o file/lfile.o file/dir.o \
file/iocompl.o file/volume.o file/deviceio.o file/dosdev.o \
- file/create.o file/find.o file/cnotify.o
+ file/create.o file/find.o
MEM_OBJECTS = mem/virtual.o mem/heap.o mem/utils.o
THREAD_OBJECTS = thread/thread.o
-PROCESS_OBJECTS = process/proc.o process/cmdline.o
+PROCESS_OBJECTS = process/proc.o
STRING_OBJECTS = string/lstring.o
EXCEPT_OBJECTS = except/except.o
-
-
OBJECTS = $(MISC_OBJECTS) $(FILE_OBJECTS) $(THREAD_OBJECTS) \
$(PROCESS_OBJECTS) $(STRING_OBJECTS) $(MEM_OBJECTS) \
$(INTERNAL_OBJECTS) $(SYNCH_OBJECTS) $(EXCEPT_OBJECTS)
kernel32.a: $(OBJECTS)
- $(AR) rcs kernel32.a $(OBJECTS)
+ $(AR) vrcs kernel32.a $(OBJECTS)
dummy:
* Put the type definitions of the heap in a seperate header. Boudewijn Dekker
*/
-/* INCLUDES *****************************************************************/
-
-#define NDEBUG
-#include <kernel32/kernel32.h>
-
#include <kernel32/proc.h>
+#include <kernel32/kernel32.h>
#include <kernel32/heap.h>
#include <internal/string.h>
-/* GLOBALS ******************************************************************/
+#include <ddk/ntddk.h>
+
static HEAP_BUCKET __HeapDefaultBuckets[]=
{
{ NULL, 256, 15, 4088 },
};
-PHEAP __ProcessHeap = NULL;
-
-/* FUNCTIONS ****************************************************************/
+PHEAP __ProcessHeap;
static BOOL __HeapCommit(PHEAP pheap, LPVOID start, LPVOID end);
static BOOL __HeapDecommit(PHEAP pheap, LPVOID start, LPVOID end);
static PHEAP __HeapPrepare(LPVOID base, ULONG minsize, ULONG maxsize,
ULONG flags);
+
+
/*********************************************************************
* __HeapCommit *
* *
*********************************************************************/
static BOOL __HeapCommit(PHEAP pheap, LPVOID start, LPVOID end)
{
- DPRINT("__HeapCommit( 0x%lX, 0x%lX, 0x%lX)\n",
- (ULONG) pheap, (ULONG) start, (ULONG) end);
+ dprintf("__HeapCommit( 0x%lX, 0x%lX, 0x%lX)\n",
+ (ULONG) pheap, (ULONG) start, (ULONG) end);
if(end >= pheap->LastBlock)
pheap->LastBlock=end;
*********************************************************************/
static BOOL __HeapDecommit(PHEAP pheap, LPVOID start, LPVOID end)
{
- DPRINT("__HeapDecommit( 0x%lX, 0x%lX, 0x%lX)\n",
+ dprintf("__HeapDecommit( 0x%lX, 0x%lX, 0x%lX)\n",
(ULONG) pheap, (ULONG) start, (ULONG) end);
#ifdef NOT
__VirtualDump();
ULONG freesize;
ULONG allocsize;
- DPRINT("__HeapAlloc(pheap %x, flags %x, size %d, tag %x)\n",
+ dprintf("__HeapAlloc(pheap %x, flags %x, size %d, tag %x)\n",
pheap,flags,size,tag);
pfree=&(pheap->Start);
*/
if(size==0)
{
- DPRINT("__HeapReAlloc: freeing memory\n");
+ dprintf("__HeapReAlloc: freeing memory\n");
__HeapFree(pheap, flags, pold);
return NULL;
}
#endif
else if(newsize < allocsize )
{
- DPRINT("__HeapReAlloc: shrinking memory\n");
+ dprintf("__HeapReAlloc: shrinking memory\n");
/* free remaining region of memory */
prealloc->Size=size | HEAP_NORMAL_TAG;
pnext=HEAP_NEXT(prealloc);
}
else if(newsize == allocsize )
{
- DPRINT("__HeapReAlloc: no changes\n");
+ dprintf("__HeapReAlloc: no changes\n");
/* nothing to do */
prealloc->Size= size | HEAP_NORMAL_TAG;
return pold;
if(((LPVOID) pnext< pheap->End)&& HEAP_ISFREE(pnext) &&
(HEAP_SIZE(pnext) + HEAP_ADMIN_SIZE >=newsize-allocsize))
{
- DPRINT("__HeapReAlloc: joining memory\n");
+ dprintf("__HeapReAlloc: joining memory\n");
oldsize=HEAP_SIZE(prealloc);
prealloc->Size=size | HEAP_NORMAL_TAG;
{
if((flags&HEAP_REALLOC_IN_PLACE_ONLY)==0)
{
- DPRINT("__HeapReAlloc: allocating new memory\n");
+ dprintf("__HeapReAlloc: allocating new memory\n");
/* alloc a new piece of memory */
oldsize=HEAP_SIZE(prealloc);
pmem=__HeapAlloc(pheap, flags, size, HEAP_NORMAL_TAG);
PHEAP_BUCKET pbucket;
PHEAP_SUBALLOC psub;
PHEAP_FRAGMENT pfrag=(PHEAP_FRAGMENT)
- ((LPVOID)pfree-HEAP_FRAG_ADMIN_SIZE);
+ ((DWORD)pfree - HEAP_FRAG_ADMIN_SIZE);
INT nalloc;
/* sanity checks */
pfrag->FreeNext=NULL;
}
}
+
return TRUE;
}
{
PHEAP pheap=(PHEAP) base;
- DPRINT("__HeapPrepare(base %x, minsize %d, maxsize %d, flags %x)\n",
+ dprintf("__HeapPrepare(base %x, minsize %d, maxsize %d, flags %x)\n",
base,minsize,maxsize,flags);
pheap->Magic=MAGIC_HEAP;
VOID WINAPI __HeapInit(LPVOID base, ULONG minsize, ULONG maxsize)
{
- base = VirtualAlloc(base,maxsize,MEM_RESERVE,PAGE_READWRITE);
- VirtualAlloc(base,PAGESIZE,MEM_COMMIT,PAGE_READWRITE);
-
- __HeapPrepare(base, minsize, maxsize, 0);
+ __ProcessHeap = VirtualAlloc(base, maxsize, MEM_RESERVE, PAGE_READWRITE);
+ VirtualAlloc(__ProcessHeap, PAGESIZE, MEM_COMMIT, PAGE_READWRITE);
+ __HeapPrepare(__ProcessHeap, minsize, maxsize, 0);
}
*********************************************************************/
LPVOID STDCALL HeapAlloc(HANDLE hheap, DWORD flags, DWORD size)
{
+
PHEAP pheap=hheap;
LPVOID retval;
- DPRINT("HeapAlloc( 0x%lX, 0x%lX, 0x%lX )\n",
+ aprintf("HeapAlloc( 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) size );
#ifdef NOT
HeapValidate(hheap, 0, 0);
if( (flags | pheap->Flags) & HEAP_NO_SERIALIZE )
LeaveCriticalSection(&(pheap->Synchronize));
- DPRINT("HeapAlloc returns 0x%lX\n", (ULONG) retval);
+ aprintf("HeapAlloc returns 0x%lX\n", (ULONG) retval);
return retval;
+
}
/*********************************************************************
*********************************************************************/
LPVOID STDCALL HeapReAlloc(HANDLE hheap, DWORD flags, LPVOID ptr, DWORD size)
{
+
PHEAP pheap=hheap;
PHEAP_BLOCK pfree=((PHEAP_BLOCK)ptr-1);
LPVOID retval;
- DPRINT("HeapReAlloc( 0x%lX, 0x%lX, 0x%lX, 0x%lX )\n",
+ aprintf("HeapReAlloc( 0x%lX, 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) ptr, size );
#ifdef NOT
HeapValidate(hheap, 0, 0);
LeaveCriticalSection(&(pheap->Synchronize));
return retval;
+
+
}
/*********************************************************************
*********************************************************************/
WINBOOL STDCALL HeapFree(HANDLE hheap, DWORD flags, LPVOID ptr)
{
+
PHEAP pheap=hheap;
- PHEAP_BLOCK pfree=(PHEAP_BLOCK)((LPVOID)ptr-HEAP_ADMIN_SIZE);
+ PHEAP_BLOCK pfree=(PHEAP_BLOCK)((DWORD)ptr-HEAP_ADMIN_SIZE);
BOOL retval;
- DPRINT("HeapFree( 0x%lX, 0x%lX, 0x%lX )\n",
+ aprintf("HeapFree( 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) ptr );
#ifdef NOT
HeapValidate(hheap, 0, 0);
EnterCriticalSection(&(pheap->Synchronize));
if(HEAP_ISNORMAL(pfree))
- retval=__HeapFree(pheap, flags, ptr);
+ {
+ retval=__HeapFree(pheap, flags, ptr);
+ }
else if(HEAP_ISFRAG(pfree))
- retval=__HeapFreeFragment(pheap, flags, ptr);
+ {
+ retval=__HeapFreeFragment(pheap, flags, ptr);
+ }
else
- retval=__ErrorReturnFalse(ERROR_INVALID_PARAMETER);
+ {
+ retval=__ErrorReturnFalse(ERROR_INVALID_PARAMETER);
+ }
if( (flags| pheap->Flags) & HEAP_NO_SERIALIZE )
LeaveCriticalSection(&(pheap->Synchronize));
return retval;
+
}
/*********************************************************************
*********************************************************************/
HANDLE WINAPI GetProcessHeap(VOID)
{
- DPRINT("GetProcessHeap()\n");
+ aprintf("GetProcessHeap()\n");
return (HANDLE) __ProcessHeap;
}
DWORD retval;
PHEAP pheap;
- DPRINT("GetProcessHeaps( %u, 0x%lX )\n", maxheaps, (ULONG) phandles );
+ aprintf("GetProcessHeaps( %u, 0x%lX )\n", maxheaps, (ULONG) phandles );
pheap= __ProcessHeap;
retval=0;
{
PHEAP pheap=hheap;
- DPRINT("HeapLock( 0x%lX )\n", (ULONG) hheap );
+ aprintf("HeapLock( 0x%lX )\n", (ULONG) hheap );
EnterCriticalSection(&(pheap->Synchronize));
return TRUE;
{
PHEAP pheap=hheap;
- DPRINT("HeapUnlock( 0x%lX )\n", (ULONG) hheap );
+ aprintf("HeapUnlock( 0x%lX )\n", (ULONG) hheap );
LeaveCriticalSection(&(pheap->Synchronize));
return TRUE;
PHEAP_BLOCK palloc=((PHEAP_BLOCK)pmem-1);
DWORD retval=0;
- DPRINT("HeapSize( 0x%lX, 0x%lX, 0x%lX )\n",
+ aprintf("HeapSize( 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) pmem );
if(pheap->Magic!=MAGIC_HEAP)
pnext=HEAP_NEXT(pcheck);
if((pprev)&&(HEAP_PREV(pcheck)!=pprev))
{
- DPRINT("HeapValidate: linked list invalid, region 0x%lX,"
+ dprintf("HeapValidate: linked list invalid, region 0x%lX,"
" previous region 0x%lX, list says 0x%lX\n",
(ULONG)pcheck, (ULONG)pprev, (ULONG) HEAP_PREV(pcheck));
return FALSE;
pnextfrag=(PHEAP_FRAGMENT)((LPVOID)pfrag+add);
if(pfrag->Magic!=HEAP_FRAG_MAGIC)
{
- DPRINT("HeapValidate: fragment %d magic invalid, region 0x%lX,"
+ dprintf("HeapValidate: fragment %d magic invalid, region 0x%lX,"
" previous region 0x%lX\n", i, (ULONG)pcheck, (ULONG)pprev);
return FALSE;
}
if(pfrag->Number!=i)
{
- DPRINT("HeapValidate: fragment %d number invalid, region 0x%lX,"
+ dprintf("HeapValidate: fragment %d number invalid, region 0x%lX,"
" previous region 0x%lX\n", i, (ULONG)pcheck, (ULONG)pprev);
return FALSE;
}
number++;
if(pfrag->Sub!=psub)
{
- DPRINT("HeapValidate: fragment %d suballoc invalid, region 0x%lX,"
+ dprintf("HeapValidate: fragment %d suballoc invalid, region 0x%lX,"
" previous region 0x%lX\n", i, (ULONG)pcheck, (ULONG)pprev);
return FALSE;
}
}
if(number!=psub->NumberFree)
{
- DPRINT("HeapValidate: invalid number of free fragments, region 0x%lX,"
+ dprintf("HeapValidate: invalid number of free fragments, region 0x%lX,"
" previous region 0x%lX\n", (ULONG)pcheck, (ULONG)pprev);
return FALSE;
}
- DPRINT("HeapValidate: [0x%08lX-0x%08lX] suballocated,"
+ dprintf("HeapValidate: [0x%08lX-0x%08lX] suballocated,"
" bucket size=%d, bitmap=0x%08lX\n",
(ULONG) pcheck, (ULONG) pnext, pbucket->Size, psub->Bitmap);
}
{
if(HEAP_RSIZE(pcheck)!=HEAP_SIZE(pcheck))
{
- DPRINT("HeapValidate: invalid size of free region 0x%lX,"
+ dprintf("HeapValidate: invalid size of free region 0x%lX,"
" previous region 0x%lX\n",
(ULONG) pcheck, (ULONG) pprev);
return FALSE;
}
- DPRINT("HeapValidate: [0x%08lX-0x%08lX] free\n",
+ dprintf("HeapValidate: [0x%08lX-0x%08lX] free\n",
(ULONG) pcheck, (ULONG) pnext );
}
else if(HEAP_ISNORMAL(pcheck))
{
- DPRINT("HeapValidate: [0x%08lX-0x%08lX] allocated\n",
+ dprintf("HeapValidate: [0x%08lX-0x%08lX] allocated\n",
(ULONG) pcheck, (ULONG) pnext );
}
else
{
- DPRINT("HeapValidate: invalid tag %x, region 0x%lX,"
+ dprintf("HeapValidate: invalid tag %x, region 0x%lX,"
" previous region 0x%lX\n", pcheck->Size>>28,
(ULONG)pcheck, (ULONG)pprev);
return FALSE;
#include <windows.h>
-
-#define NDEBUG
#include <kernel32/kernel32.h>
VOID CopyMemory(PVOID Destination, CONST VOID* Source, DWORD Length)
{
DWORD i;
- DPRINT("CopyMemory(Destination %x, Source %x, Length %d)\n",
+ dprintf("CopyMemory(Destination %x, Source %x, Length %d)\n",
Destination,Source,Length);
for (i=0; i<Length; i++)
#include <kernel32\thread.h>
#include <wstring.h>
#include <string.h>
-// RJJ: (we dont have it) #include <stdlib.h>
+//#include <stdlib.h>
+
+
+
+
+
/* system global and local atom tables */
if(lpfree && atomlen) {
lpfree->q = q;
lpfree->refcnt = 1;
- wcsncpy(&at->AtomData[lpfree->idx],lpString,atomlen);
+ lstrcpynW(&at->AtomData[lpfree->idx],lpString,atomlen);
return freeindex + ATOMBASE;
}
if(lp->q == q) {
if(HIWORD(lpString) == 0)
return ATOMBASE + index;
- if(wcsicmp(&at->AtomData[lp->idx],lpString) == 0)
+ if(lstrcmpiW(&at->AtomData[lp->idx],lpString) == 0)
return ATOMBASE + index;
}
}
if (atomlen < len)
lstrcpyW(lpString,atomstr);
else {
- wcsncpy(lpString,atomstr,len-1);
+ lstrcpynW(lpString,atomstr,len-1);
lpString[len-1] = '\0';
}
return (UINT)lstrlenW(lpString);
--- /dev/null
+#include <windows.h>
+#include <ddk/ntddk.h>
+
+HANDLE StdInput = NULL;
+HANDLE StdOutput = NULL;
+HANDLE StdError = NULL;
+
+
+
+
+#define FSCTL_GET_CONSOLE_SCREEN_BUFFER_INFO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 254, DO_DIRECT_IO, FILE_READ_ACCESS|FILE_WRITE_ACCESS)
+#define FSCTL_SET_CONSOLE_SCREEN_BUFFER_INFO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 255, DO_DIRECT_IO, FILE_READ_ACCESS|FILE_WRITE_ACCESS)
+
+HANDLE
+STDCALL
+GetStdHandle(
+ DWORD nStdHandle
+ )
+{
+ if ( nStdHandle == STD_INPUT_HANDLE )
+ return StdInput;
+ if ( nStdHandle == STD_OUTPUT_HANDLE )
+ return StdOutput;
+ if ( nStdHandle == STD_ERROR_HANDLE )
+ return StdError;
+/*
+ if ( nStdHandle == STD_AUX_HANDLE )
+ return StdError;
+ if ( nStdHandle == STD_PRINT_HANDLE )
+ return StdError;
+*/
+ return NULL;
+
+}
+
+WINBOOL
+STDCALL
+WriteConsoleA(
+ HANDLE hConsoleOutput,
+ CONST VOID *lpBuffer,
+ DWORD nNumberOfCharsToWrite,
+ LPDWORD lpNumberOfCharsWritten,
+ LPVOID lpReserved
+ )
+{
+ return WriteFile(hConsoleOutput, lpBuffer, nNumberOfCharsToWrite,lpNumberOfCharsWritten, lpReserved);
+}
+
+
+WINBOOL
+STDCALL
+ReadConsoleA(
+ HANDLE hConsoleInput,
+ LPVOID lpBuffer,
+ DWORD nNumberOfCharsToRead,
+ LPDWORD lpNumberOfCharsRead,
+ LPVOID lpReserved
+ )
+{
+ return ReadFile(hConsoleInput,lpBuffer,nNumberOfCharsToRead,lpNumberOfCharsRead,lpReserved);
+}
+
+WINBOOL
+STDCALL
+AllocConsole( VOID )
+{
+ StdInput = CreateFile("\\Device\\Keyboard",
+ FILE_GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+
+ StdOutput = CreateFile("\\Device\\BlueScreen",
+ FILE_GENERIC_WRITE|FILE_GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+
+ StdError = StdOutput;
+
+ return TRUE;
+}
+
+
+WINBOOL
+STDCALL
+FreeConsole( VOID )
+{
+ return TRUE;
+}
+
+
+WINBOOL
+STDCALL
+GetConsoleScreenBufferInfo(
+ HANDLE hConsoleOutput,
+ PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
+ )
+{
+ DWORD dwBytesReturned;
+ if( !DeviceIoControl(hConsoleOutput,
+ FSCTL_GET_CONSOLE_SCREEN_BUFFER_INFO,
+ NULL,0,
+ lpConsoleScreenBufferInfo,sizeof(CONSOLE_SCREEN_BUFFER_INFO),&dwBytesReturned,NULL ))
+ return FALSE;
+
+ return TRUE;
+}
+
+WINBOOL
+STDCALL
+SetConsoleCursorPosition(
+ HANDLE hConsoleOutput,
+ COORD dwCursorPosition
+ )
+{
+ DWORD dwBytesReturned;
+ CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
+
+ if( !GetConsoleScreenBufferInfo(hConsoleOutput,&ConsoleScreenBufferInfo) )
+ return FALSE;
+// ConsoleScreenBufferInfo.dwCursorPosition.X = dwCursorPosition.X;
+// ConsoleScreenBufferInfo.dwCursorPosition.Y = dwCursorPosition.Y;
+ return TRUE;
+ if( !DeviceIoControl(
+ hConsoleOutput,
+ FSCTL_SET_CONSOLE_SCREEN_BUFFER_INFO,
+ &ConsoleScreenBufferInfo,
+ sizeof(CONSOLE_SCREEN_BUFFER_INFO),
+ NULL,
+ 0,
+ &dwBytesReturned,
+ NULL ))
+ return FALSE;
+
+ return TRUE;
+}
+
+WINBOOL
+STDCALL
+FillConsoleOutputCharacterA(
+ HANDLE hConsoleOutput,
+ CHAR cCharacter,
+ DWORD nLength,
+ COORD dwWriteCoord,
+ LPDWORD lpNumberOfCharsWritten
+ )
+{
+ return FillConsoleOutputCharacterW(hConsoleOutput,
+ (WCHAR) cCharacter,nLength, dwWriteCoord,lpNumberOfCharsWritten);
+}
+
+WINBOOL
+STDCALL
+FillConsoleOutputCharacterW(
+ HANDLE hConsoleOutput,
+ WCHAR cCharacter,
+ DWORD nLength,
+ COORD dwWriteCoord,
+ LPDWORD lpNumberOfCharsWritten
+ )
+{
+ return FALSE;
+}
#include <windows.h>
#include <ddk/ntddk.h>
+#include <wstring.h>
#include <kernel32/proc.h>
WINBOOL
LPVOID lpReserved );
-NT_PEB Peb;
+
+NT_TEB *Teb;
+
-NT_PEB *CurrentPeb;
-NT_TEB *Teb;
-PROCESSINFOW ProcessInfo;
ULONG ul_reason_for_call,
LPVOID lpReserved )
{
+
switch( ul_reason_for_call ) {
case DLL_PROCESS_ATTACH:
{
- CurrentPeb = &Peb;
- CurrentPeb->ProcessHeap = HeapCreate(HEAP_GENERATE_EXCEPTIONS,8192,0);
+
+ GetCurrentPeb()->ProcessHeap = HeapCreate(HEAP_GENERATE_EXCEPTIONS,8192,0);
InitAtomTable(13);
+ SetCurrentDirectoryW(L"C:");
+ // SetSystemDirectoryW(L"C:\\Reactos\\System");
+ // SetWindowsDirectoryW(L"C:\\Reactos");
+
}
case DLL_THREAD_ATTACH:
{
#include <string.h>
#define MAX_ENVIRONMENT_VARS 255
+#define MAX_VALUE 1024
typedef struct _ENV_ELEMENT
{
UNICODE_STRING Name;
UNICODE_STRING Value;
+ WINBOOL Valid;
} ENV_ELEMENT;
ENV_ELEMENT Environment[MAX_ENVIRONMENT_VARS+1];
UINT nEnvVar = 0;
-int wcsncmp2(CONST WCHAR *s, CONST WCHAR *t,UINT n);
+DWORD
+STDCALL
+GetEnvironmentVariableA(
+ LPCSTR lpName,
+ LPSTR lpBuffer,
+ DWORD nSize
+ )
+{
+ WCHAR BufferW[MAX_VALUE];
+ WCHAR NameW[MAX_PATH];
+ DWORD RetValue;
+ int i=0;
+ while ((*lpName)!=0 && i < MAX_PATH)
+ {
+ NameW[i] = *lpName;
+ lpName++;
+ i++;
+ }
+ NameW[i] = 0;
+
+ RetValue = GetEnvironmentVariableW(NameW,BufferW,nSize);
+ for(i=0;i<nSize;i++)
+ lpBuffer[i] = (char)BufferW[i];
+ return RetValue;
+}
DWORD
STDCALL
while (i < nEnvVar)
{
- if ( wcsncmp2(Environment[i].Name.Buffer,lpName,min(NameLen,Environment[i].Name.Length)) != 0 ) {
- lstrcpynW(lpBuffer,Environment[i].Value.Buffer,min(nSize,Environment[i].Value.Length));
+ if ( wcsnicmp(Environment[i].Name.Buffer,lpName,min(NameLen,Environment[i].Name.Length/sizeof(WCHAR))) != 0 ) {
+ lstrcpynW(lpBuffer,Environment[i].Value.Buffer,min(nSize,Environment[i].Value.Length/sizeof(WCHAR)));
- return lstrlenW(lpBuffer);
+ return lstrlenW(Environment[i].Value.Buffer);
}
i++;
}
-int wcsncmp2(CONST WCHAR *s, CONST WCHAR *t,UINT n)
+
+WINBOOL
+STDCALL
+SetEnvironmentVariableA(
+ LPCSTR lpName,
+ LPCSTR lpValue
+ )
{
- for(;towupper(*s) == towupper(*t) && n > 0; s++, t++, n--)
- if ( *s == 0 )
- return 0;
- return *s - *t;
-}
+ WCHAR NameW[MAX_PATH];
+ WCHAR ValueW[MAX_VALUE];
+ int i=0;
+ while ((*lpName)!=0 && i < MAX_PATH)
+ {
+ NameW[i] = *lpName;
+ lpName++;
+ i++;
+ }
+ NameW[i] = 0;
+
+ i = 0;
+
+ while ((*lpValue)!=0 && i < MAX_PATH)
+ {
+ ValueW[i] = *lpValue;
+ lpValue++;
+ i++;
+ }
+ ValueW[i] = 0;
+ return SetEnvironmentVariableW(NameW,ValueW);
+
+
+}
WINBOOL
STDCALL
while (i < nEnvVar)
{
- if ( wcsncmp2(Environment[i].Name.Buffer,lpName,min(NameLen,Environment[i].Name.Length)) != 0 ) {
- lstrcpynW(Environment[i].Value.Buffer,lpValue,min(ValueLen,Environment[i].Value.MaximumLength));
- return TRUE;
+ if ( wcsnicmp(Environment[i].Name.Buffer,lpName,min(NameLen,Environment[i].Name.Length/sizeof(WCHAR))) != 0 ) {
+ if ( lpValue != NULL ) {
+ lstrcpynW(Environment[i].Value.Buffer,lpValue,min(ValueLen,Environment[i].Value.MaximumLength/sizeof(WCHAR)));
+ return TRUE;
+ }
+ else {
+ Environment[i].Valid = FALSE;
+ Environment[i].Value.Length = 0;
+ Environment[i].Name.Length = 0;
+ return FALSE;
+ }
+
+
}
i++;
}
- if ( nEnvVar > MAX_ENVIRONMENT_VARS )
+ if ( nEnvVar >= MAX_ENVIRONMENT_VARS )
return FALSE;
- NameBuffer = (WCHAR *)HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,MAX_PATH*sizeof(WCHAR));
- ValueBuffer = (WCHAR *)HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,1024*sizeof(WCHAR));
+
+ while (i < nEnvVar)
+ {
+ if ( Environment[i].Valid == FALSE )
+ break;
+ i++;
+ }
+ if ( i == nEnvVar ) {
+ NameBuffer = (WCHAR *)HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,MAX_PATH*sizeof(WCHAR) );
+ ValueBuffer = (WCHAR *)HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,MAX_VALUE*sizeof(WCHAR) );
- Environment[i].Name.Buffer = NameBuffer;
- Environment[i].Name.MaximumLength = MAX_PATH;
- lstrcpynW(Environment[i].Name.Buffer,lpValue,min(NameLen,Environment[i].Name.MaximumLength));
- Environment[i].Name.Length = NameLen;
-
- Environment[i].Value.Buffer = ValueBuffer;
- Environment[i].Value.MaximumLength = 1024;
- lstrcpynW(Environment[i].Value.Buffer,lpValue,min(ValueLen,Environment[i].Value.MaximumLength));
- Environment[i].Value.Length = ValueLen;
+ Environment[i].Name.Buffer = NameBuffer;
+ Environment[i].Name.MaximumLength = MAX_PATH*sizeof(WCHAR);
+
+ Environment[i].Value.Buffer = ValueBuffer;
+ Environment[i].Value.MaximumLength = MAX_VALUE*sizeof(WCHAR);
+ nEnvVar++;
+ }
+ Environment[i].Valid = TRUE;
+
+ lstrcpynW(Environment[i].Name.Buffer,lpValue,min(NameLen,(Environment[i].Name.MaximumLength-sizeof(WCHAR))/sizeof(WCHAR)));
+ Environment[i].Name.Length = NameLen*sizeof(WCHAR);
+
+
+ lstrcpynW(Environment[i].Value.Buffer,lpValue,min(ValueLen,(Environment[i].Value.MaximumLength-sizeof(WCHAR)))/sizeof(WCHAR));
+ Environment[i].Value.Length = ValueLen*sizeof(WCHAR);
- nEnvVar++;
return TRUE;
lpVersionInformation->dwMinorVersion = 0;
lpVersionInformation->dwBuildNumber = 12;
lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
- lstrcpyW((WCHAR *)lpVersionInformation->szCSDVersion,L"ReactOs Pre-Alpha 12");
+ lstrcpyW((WCHAR *)lpVersionInformation->szCSDVersion,L"Ariadne was here...");
return TRUE;
}
lpVersionInformation->dwMinorVersion = 0;
lpVersionInformation->dwBuildNumber = 12;
lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
- lstrcpyA((char *)lpVersionInformation->szCSDVersion,"ReactOs Pre-Alpha 12");
+ lstrcpyA((char *)lpVersionInformation->szCSDVersion,"ReactOs Pre-Alpha");
+ return TRUE;
+}
+
+VOID GetSystemTime(
+ LPSYSTEMTIME lpSystemTime
+ )
+{
+ NTSTATUS errCode;
+memset(lpSystemTime,sizeof(SYSTEMTIME),0);
+// errCode = NtQuerySystemTime (
+// (TIME *)lpSystemTime
+// );
+ return;
+}
+
+WINBOOL
+STDCALL
+SetSystemTime(
+ CONST SYSTEMTIME *lpSystemTime
+ )
+{
+ NTSTATUS errCode;
+ LARGE_INTEGER NewSystemTime;
+ errCode = NtSetSystemTime (
+ (LARGE_INTEGER *)lpSystemTime,
+ &NewSystemTime
+ );
+ if ( !NT_SUCCESS(errCode) )
+ return FALSE;
+ return TRUE;
+}
+
+
+
+
+
+
+VOID
+STDCALL
+GetLocalTime(
+ LPSYSTEMTIME lpSystemTime
+ )
+{
+ GetSystemTime(lpSystemTime);
+}
+
+
+WINBOOL
+STDCALL
+SetLocalTime(
+ CONST SYSTEMTIME *lpSystemTime
+ )
+{
+ return SetSystemTime(lpSystemTime);
+}
+
+LPSTR
+STDCALL
+GetEnvironmentStringsA(
+ VOID
+ )
+{
+ WCHAR *EnvironmentStringsW;
+ char *EnvironmentStringsA;
+ int size = 0;
+ int i;
+ EnvironmentStringsW = GetEnvironmentStringsW();
+ EnvironmentStringsA = (char *)EnvironmentStringsW;
+
+ for(i=0;i<nEnvVar;i++) {
+ if ( Environment[i].Valid ) {
+ size += Environment[i].Name.Length;
+ size += sizeof(WCHAR); // =
+ size += Environment[i].Value.Length;
+ size += sizeof(WCHAR); // zero
+ }
+ }
+ size += sizeof(WCHAR);
+ size /= sizeof(WCHAR);
+ for(i=0;i<size;i++)
+ EnvironmentStringsA[i] = (char)EnvironmentStringsW[i];
+ return EnvironmentStringsA;
+}
+
+
+LPWSTR
+STDCALL
+GetEnvironmentStringsW(
+ VOID
+ )
+{
+ int size = 0;
+ int i;
+ WCHAR *EnvironmentString;
+ WCHAR *EnvironmentStringSave;
+ for(i=0;i<nEnvVar;i++) {
+ if ( Environment[i].Valid ) {
+ size += Environment[i].Name.Length;
+ size += sizeof(WCHAR); // =
+ size += Environment[i].Value.Length;
+ size += sizeof(WCHAR); // zero
+ }
+ }
+ size += sizeof(WCHAR); // extra zero
+ EnvironmentString = (WCHAR *)HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,size);
+ EnvironmentStringSave = EnvironmentString;
+ for(i=0;i<nEnvVar;i++) {
+ if ( Environment[i].Valid ) {
+ wcscpy(EnvironmentString,Environment[i].Name.Buffer);
+ wcscat(EnvironmentString,L"=");
+ wcscat(EnvironmentString,Environment[i].Value.Buffer);
+
+ size = Environment[i].Name.Length;
+ size += sizeof(WCHAR); // =
+ size += Environment[i].Value.Length;
+ size += sizeof(WCHAR); // zero
+ EnvironmentString += (size/sizeof(WCHAR));
+ }
+ }
+ EnvironmentString++;
+ *EnvironmentString = 0;
+ return EnvironmentStringSave;
+}
+
+
+WINBOOL
+STDCALL
+FreeEnvironmentStringsA(
+ LPSTR EnvironmentStrings
+ )
+{
+ if ( EnvironmentStrings == NULL )
+ return FALSE;
+ HeapFree(GetProcessHeap(),0,EnvironmentStrings);
+ return TRUE;
+}
+
+WINBOOL
+STDCALL
+FreeEnvironmentStringsW(
+ LPWSTR EnvironmentStrings
+ )
+{
+ if ( EnvironmentStrings == NULL )
+ return FALSE;
+ HeapFree(GetProcessHeap(),0,EnvironmentStrings);
return TRUE;
}
return(0);
}
+
VOID SetLastError(DWORD dwErrorCode)
{
LastError = dwErrorCode;
* UPDATE HISTORY:
* Created 01/11/98
*/
-
-/* INCLUDES ****************************************************************/
-
#define UNICODE
#include <windows.h>
#include <kernel32/proc.h>
#include <ddk/rtl.h>
#include <ddk/li.h>
-/* GLOBALS *****************************************************************/
+NT_PEB CurrentPeb;
+
-extern NT_PEB *CurrentPeb;
-extern NT_PEB Peb;
WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
-/* FUNCTIONS ****************************************************************/
+wchar_t **CommandLineToArgvW(LPCWSTR lpCmdLine, int * pNumArgs );
+
+WINBOOL
+STDCALL
+GetProcessId(HANDLE hProcess, LPDWORD lpProcessId );
+
+
-WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId);
NT_PEB *GetCurrentPeb(VOID)
{
- if ( CurrentPeb != NULL )
- return CurrentPeb;
- else // hack to be able to return a process environment any time.
- return &Peb;
+ return &CurrentPeb;
+
}
HANDLE STDCALL GetCurrentProcess(VOID)
return (HANDLE)NtCurrentThread();
}
-DWORD STDCALL GetCurrentProcessId(VOID)
-{
- return (DWORD)(GetTeb()->Cid).UniqueProcess;
+DWORD
+STDCALL
+GetCurrentProcessId(VOID)
+{
+
+ return (DWORD)(GetTeb()->Cid).UniqueProcess;
+
+
}
-WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode )
+unsigned char CommandLineA[MAX_PATH];
+
+LPSTR
+STDCALL
+GetCommandLineA(
+ VOID
+ )
{
- NTSTATUS errCode;
- PROCESS_BASIC_INFORMATION ProcessBasic;
- ULONG BytesWritten;
-
- errCode = NtQueryInformationProcess(hProcess,
- ProcessBasicInformation,
- &ProcessBasic,
- sizeof(PROCESS_BASIC_INFORMATION),
- &BytesWritten);
- if (!NT_SUCCESS(errCode))
- {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
- }
- memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
- return TRUE;
+ WCHAR *CommandLineW;
+ ULONG i = 0;
+
+ CommandLineW = GetCommandLineW();
+ while ((CommandLineW[i])!=0 && i < MAX_PATH)
+ {
+ CommandLineA[i] = (unsigned char)CommandLineW[i];
+ i++;
+ }
+ CommandLineA[i] = 0;
+ return CommandLineA;
+}
+LPWSTR
+STDCALL
+GetCommandLineW(
+ VOID
+ )
+{
+ return GetCurrentPeb()->StartupInfo->CommandLine;
}
-WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId )
+wchar_t **CommandLineToArgvW(LPCWSTR lpCmdLine, int * pNumArgs )
{
- NTSTATUS errCode;
- PROCESS_BASIC_INFORMATION ProcessBasic;
- ULONG BytesWritten;
-
- errCode = NtQueryInformationProcess(hProcess,
- ProcessBasicInformation,
- &ProcessBasic,
- sizeof(PROCESS_BASIC_INFORMATION),
- &BytesWritten);
- if (!NT_SUCCESS(errCode))
- {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
- }
- memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
- return TRUE;
+ return NULL;
+}
+
+
+
+WINBOOL
+STDCALL
+GetExitCodeProcess(
+ HANDLE hProcess,
+ LPDWORD lpExitCode
+ )
+{
+ NTSTATUS errCode;
+ PROCESS_BASIC_INFORMATION ProcessBasic;
+ ULONG BytesWritten;
+
+ errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
+ return TRUE;
+
}
-PWSTR InternalAnsiToUnicode(PWSTR Out, LPCSTR In, ULONG MaxLength)
+WINBOOL
+STDCALL
+GetProcessId(
+ HANDLE hProcess,
+ LPDWORD lpProcessId
+ )
{
- ULONG i;
-
- if (In == NULL)
- {
- return(NULL);
- }
- else
- {
- i = 0;
- while ((*In)!=0 && i < MaxLength)
- {
- Out[i] = *In;
- In++;
- i++;
- }
- Out[i] = 0;
- return(Out);
- }
+ NTSTATUS errCode;
+ PROCESS_BASIC_INFORMATION ProcessBasic;
+ ULONG BytesWritten;
+
+ errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
+ return TRUE;
+
}
-WINBOOL STDCALL CreateProcessA(LPCSTR lpApplicationName,
- LPSTR lpCommandLine,
- LPSECURITY_ATTRIBUTES lpProcessAttributes,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- WINBOOL bInheritHandles,
- DWORD dwCreationFlags,
- LPVOID lpEnvironment,
- LPCSTR lpCurrentDirectory,
- LPSTARTUPINFO lpStartupInfo,
- LPPROCESS_INFORMATION lpProcessInformation)
-/*
- * FUNCTION: The CreateProcess function creates a new process and its
- * primary thread. The new process executes the specified executable file
- * ARGUMENTS:
- *
- * lpApplicationName = Pointer to name of executable module
- * lpCommandLine = Pointer to command line string
- * lpProcessAttributes = Process security attributes
- * lpThreadAttributes = Thread security attributes
- * bInheritHandles = Handle inheritance flag
- * dwCreationFlags = Creation flags
- * lpEnvironment = Pointer to new environment block
- * lpCurrentDirectory = Pointer to current directory name
- * lpStartupInfo = Pointer to startup info
- * lpProcessInformation = Pointer to process information
- */
+WINBOOL
+STDCALL
+CreateProcessA(
+ LPCSTR lpApplicationName,
+ LPSTR lpCommandLine,
+ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ WINBOOL bInheritHandles,
+ DWORD dwCreationFlags,
+ LPVOID lpEnvironment,
+ LPCSTR lpCurrentDirectory,
+ LPSTARTUPINFO lpStartupInfo,
+ LPPROCESS_INFORMATION lpProcessInformation
+ )
{
- WCHAR ApplicationNameW[MAX_PATH];
- WCHAR CommandLineW[MAX_PATH];
- WCHAR CurrentDirectoryW[MAX_PATH];
- PWSTR PApplicationNameW;
- PWSTR PCommandLineW;
- PWSTR PCurrentDirectoryW;
- ULONG i;
-
- OutputDebugStringA("CreateProcessA\n");
-
- PApplicationNameW = InternalAnsiToUnicode(ApplicationNameW,
- lpApplicationName,
- MAX_PATH);
- PCommandLineW = InternalAnsiToUnicode(CommandLineW,
- lpCommandLine,
- MAX_PATH);
- PCurrentDirectoryW = InternalAnsiToUnicode(CurrentDirectoryW,
- lpCurrentDirectory,
- MAX_PATH);
- return CreateProcessW(PApplicationNameW,
- PCommandLineW,
- lpProcessAttributes,
- lpThreadAttributes,
- bInheritHandles,
- dwCreationFlags,
- lpEnvironment,
- PCurrentDirectoryW,
- lpStartupInfo,
- lpProcessInformation);
+ WCHAR ApplicationNameW[MAX_PATH];
+ WCHAR CommandLineW[MAX_PATH];
+ WCHAR CurrentDirectoryW[MAX_PATH];
+
+
+ ULONG i;
+
+ i = 0;
+ while ((*lpApplicationName)!=0 && i < MAX_PATH)
+ {
+ ApplicationNameW[i] = *lpApplicationName;
+ lpApplicationName++;
+ i++;
+ }
+ ApplicationNameW[i] = 0;
+
+
+ i = 0;
+ while ((*lpCommandLine)!=0 && i < MAX_PATH)
+ {
+ CommandLineW[i] = *lpCommandLine;
+ lpCommandLine++;
+ i++;
+ }
+ CommandLineW[i] = 0;
+
+ i = 0;
+ while ((*lpCurrentDirectory)!=0 && i < MAX_PATH)
+ {
+ CurrentDirectoryW[i] = *lpCurrentDirectory;
+ lpCurrentDirectory++;
+ i++;
+ }
+ CurrentDirectoryW[i] = 0;
+
+ return CreateProcessW(ApplicationNameW,CommandLineW, lpProcessAttributes,lpThreadAttributes,
+ bInheritHandles,dwCreationFlags,lpEnvironment,CurrentDirectoryW,lpStartupInfo,
+ lpProcessInformation);
+
+
}
-WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
- LPWSTR lpCommandLine,
- LPSECURITY_ATTRIBUTES lpProcessAttributes,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- WINBOOL bInheritHandles,
- DWORD dwCreationFlags,
- LPVOID lpEnvironment,
- LPCWSTR lpCurrentDirectory,
- LPSTARTUPINFO lpStartupInfo,
- LPPROCESS_INFORMATION lpProcessInformation)
+WINBOOL
+STDCALL
+CreateProcessW(
+ LPCWSTR lpApplicationName,
+ LPWSTR lpCommandLine,
+ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ WINBOOL bInheritHandles,
+ DWORD dwCreationFlags,
+ LPVOID lpEnvironment,
+ LPCWSTR lpCurrentDirectory,
+ LPSTARTUPINFO lpStartupInfo,
+ LPPROCESS_INFORMATION lpProcessInformation
+ )
{
- HANDLE hFile, hSection, hProcess, hThread;
- KPRIORITY PriorityClass;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- BOOLEAN CreateSuspended;
- NTSTATUS errCode;
- UNICODE_STRING ApplicationNameString;
- LPTHREAD_START_ROUTINE lpStartAddress = NULL;
- LPVOID lpParameter = NULL;
- PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
- WCHAR TempApplicationName[255];
- WCHAR TempFileName[255];
- WCHAR TempDirectoryName[255];
- ULONG i;
- ULONG BaseAddress;
- ULONG Size;
- LARGE_INTEGER SectionOffset;
-
- dprintf("CreateProcessW(lpApplicationName '%w', lpCommandLine '%w')\n",
- lpApplicationName,lpCommandLine);
-
- hFile = NULL;
-
- /*
- * Find the application name
- */
- TempApplicationName[0] = '\\';
- TempApplicationName[1] = '?';
- TempApplicationName[2] = '?';
- TempApplicationName[3] = '\\';
- TempApplicationName[4] = 0;
-
- dprintf("TempApplicationName '%w'\n",TempApplicationName);
-
- if (lpApplicationName != NULL)
- {
- wcscpy(TempFileName, lpApplicationName);
-
- dprintf("TempFileName '%w'\n",TempFileName);
- }
- else
- {
- wcscpy(TempFileName, lpCommandLine);
-
- dprintf("TempFileName '%w'\n",TempFileName);
-
- for (i=0; TempFileName[i]!=' ' && TempFileName[i] != 0; i++);
- TempFileName[i]=0;
-
- }
- if (TempFileName[1] != ':')
- {
- GetCurrentDirectoryW(MAX_PATH,TempDirectoryName);
- wcscat(TempApplicationName,TempDirectoryName);
- }
- wcscat(TempApplicationName,TempFileName);
-
- RtlInitUnicodeString(&ApplicationNameString, TempApplicationName);
-
- dprintf("ApplicationName %w\n",ApplicationNameString.Buffer);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &ApplicationNameString,
- OBJ_CASE_INSENSITIVE,
- NULL,
- SecurityDescriptor);
-
- /*
- * Try to open the executable
- */
-
- errCode = NtOpenFile(&hFile,
- SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
- &ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_DELETE|FILE_SHARE_READ,
- FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
-
- if ( !NT_SUCCESS(errCode) )
- {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
- }
-
- errCode = NtCreateSection(&hSection,
- SECTION_ALL_ACCESS,
- NULL,
- NULL,
- PAGE_EXECUTE,
- SEC_IMAGE,
- hFile);
- NtClose(hFile);
-
- if ( !NT_SUCCESS(errCode) )
- {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
- }
-
- errCode = NtCreateProcess(&hProcess,
- PROCESS_ALL_ACCESS,
- NULL,
- NtCurrentProcess(),
- bInheritHandles,
- NULL,
- NULL,
- NULL);
-
- BaseAddress = (PVOID)0x10000;
- LARGE_INTEGER_QUAD_PART(SectionOffset) = 0;
- Size = 0x10000;
- NtMapViewOfSection(hSection,
- hProcess,
- &BaseAddress,
- 0,
- Size,
- &SectionOffset,
- &Size,
- 0,
- MEM_COMMIT,
- PAGE_READWRITE);
+ HANDLE hFile, hSection, hProcess, hThread;
+ KPRIORITY PriorityClass;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ BOOLEAN CreateSuspended;
+
+ NTSTATUS errCode;
-
- NtClose(hSection);
+ UNICODE_STRING ApplicationNameString;
+
- if ( !NT_SUCCESS(errCode) )
- {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
- }
+
+ LPTHREAD_START_ROUTINE lpStartAddress = NULL;
+ LPVOID lpParameter = NULL;
+
+ hFile = NULL;
+
+ ApplicationNameString.Length = lstrlenW(lpApplicationName)*sizeof(WCHAR);
-#if 0
- PriorityClass = NORMAL_PRIORITY_CLASS;
- NtSetInformationProcess(hProcess,
- ProcessBasePriority,
- &PriorityClass,
- sizeof(KPRIORITY));
-#endif
- dprintf("Creating thread for process\n");
- lpStartAddress = BaseAddress;
- hThread = CreateRemoteThread(hProcess,
- lpThreadAttributes,
- 4096, // 1 page ??
- lpStartAddress,
- lpParameter,
- dwCreationFlags,
- &lpProcessInformation->dwThreadId);
-
- if ( hThread == NULL )
- return FALSE;
-
- lpProcessInformation->hProcess = hProcess;
- lpProcessInformation->hThread = hThread;
-
- GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
-
- return TRUE;
-}
+ ApplicationNameString.Buffer = (WCHAR *)lpApplicationName;
+ ApplicationNameString.MaximumLength = ApplicationNameString.Length+sizeof(WCHAR);
+
+
+ ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+ ObjectAttributes.RootDirectory = NULL;
+
+
+
+ if ( lpProcessAttributes != NULL ) {
+ if ( lpProcessAttributes->bInheritHandle )
+ ObjectAttributes.Attributes = OBJ_INHERIT;
+ else
+ ObjectAttributes.Attributes = 0;
+ ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
+ }
+ ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
+
+ errCode = NtOpenFile(&hFile,(SYNCHRONIZE|FILE_EXECUTE), &ObjectAttributes,
+ &IoStatusBlock,(FILE_SHARE_DELETE|FILE_SHARE_READ),(FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE));
+
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+
+ errCode = NtCreateSection(&hSection,SECTION_ALL_ACCESS,NULL,NULL,PAGE_EXECUTE,SEC_IMAGE,hFile);
+ NtClose(hFile);
+
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+
+
+ if ( lpProcessAttributes != NULL ) {
+ if ( lpProcessAttributes->bInheritHandle )
+ ObjectAttributes.Attributes = OBJ_INHERIT;
+ else
+ ObjectAttributes.Attributes = 0;
+ ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
+ }
+
+ errCode = NtCreateProcess(&hProcess,PROCESS_ALL_ACCESS, &ObjectAttributes,NtCurrentProcess(),bInheritHandles,hSection,NULL,NULL);
+ NtClose(hSection);
+
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+
+ PriorityClass = NORMAL_PRIORITY_CLASS;
+ NtSetInformationProcess(hProcess,ProcessBasePriority,&PriorityClass,sizeof(KPRIORITY));
+
+ if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED)
+ CreateSuspended = TRUE;
+ else
+ CreateSuspended = FALSE;
+
+ hThread = CreateRemoteThread(
+ hProcess,
+ lpThreadAttributes,
+ 4096, // 1 page ??
+ lpStartAddress,
+ lpParameter,
+ CREATE_SUSPENDED,
+ &lpProcessInformation->dwThreadId
+ );
+
+
+ if ( hThread == NULL )
+ return FALSE;
+
+
+
+ lpProcessInformation->hProcess = hProcess;
+ lpProcessInformation->hThread = hThread;
+
+
+
+ GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
+
-HANDLE STDCALL OpenProcess(DWORD dwDesiredAccess,
- WINBOOL bInheritHandle,
- DWORD dwProcessId)
+ return TRUE;
+
+
+ }
+
+
+
+HANDLE
+STDCALL
+OpenProcess(
+ DWORD dwDesiredAccess,
+ WINBOOL bInheritHandle,
+ DWORD dwProcessId
+ )
{
- NTSTATUS errCode;
- HANDLE ProcessHandle;
- OBJECT_ATTRIBUTES ObjectAttributes;
- CLIENT_ID ClientId ;
-
- ClientId.UniqueProcess = (HANDLE)dwProcessId;
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = (HANDLE)NULL;
- ObjectAttributes.SecurityDescriptor = NULL;
- ObjectAttributes.SecurityQualityOfService = NULL;
-
- if ( bInheritHandle == TRUE )
- ObjectAttributes.Attributes = OBJ_INHERIT;
- else
- ObjectAttributes.Attributes = 0;
-
- errCode = NtOpenProcess(&ProcessHandle,
- dwDesiredAccess,
- &ObjectAttributes,
- &ClientId);
- if (!NT_SUCCESS(errCode))
- {
- SetLastError(RtlNtStatusToDosError(errCode));
- return NULL;
- }
- return ProcessHandle;
+
+
+ NTSTATUS errCode;
+ HANDLE ProcessHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ CLIENT_ID ClientId ;
+
+ ClientId.UniqueProcess = (HANDLE)dwProcessId;
+ ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+ ObjectAttributes.RootDirectory = (HANDLE)NULL;
+ ObjectAttributes.SecurityDescriptor = NULL;
+ ObjectAttributes.SecurityQualityOfService = NULL;
+
+ if ( bInheritHandle == TRUE )
+ ObjectAttributes.Attributes = OBJ_INHERIT;
+ else
+ ObjectAttributes.Attributes = 0;
+
+ errCode = NtOpenProcess ( &ProcessHandle, dwDesiredAccess, &ObjectAttributes, &ClientId);
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return NULL;
+ }
+ return ProcessHandle;
}
}
-
VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle)
{
lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
BOOL bAlertable
)
{
- TIME Interval;
+ LARGE_INTEGER Interval;
NTSTATUS errCode;
+ SET_LARGE_INTEGER_LOW_PART(Interval,dwMilliseconds*1000);
- Interval.LowPart = dwMilliseconds * 1000;
- Interval.HighPart = 0;
errCode = NtDelayExecution(bAlertable,&Interval);
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
}
lpStartupInfo->cb = sizeof(STARTUPINFO);
- lstrcpyW(lpStartupInfo->lpDesktop, pPeb->StartupInfo->Desktop);
- lstrcpyW(lpStartupInfo->lpTitle, pPeb->StartupInfo->Title);
+ lstrcpyW(lpStartupInfo->lpDesktop,(WCHAR *) pPeb->StartupInfo->Desktop);
+ lstrcpyW(lpStartupInfo->lpTitle, (WCHAR *)pPeb->StartupInfo->Title);
lpStartupInfo->dwX = pPeb->StartupInfo->dwX;
lpStartupInfo->dwY = pPeb->StartupInfo->dwY;
lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize;
while ((pPeb->StartupInfo->Desktop[i])!=0 && i < MAX_PATH)
{
- lpStartupInfo->lpDesktop[i] = (unsigned char)pPeb->StartupInfo->Desktop[i];
+ lpStartupInfo->lpDesktop[i] = (char)pPeb->StartupInfo->Desktop[i];
i++;
}
lpStartupInfo->lpDesktop[i] = 0;
i = 0;
while ((pPeb->StartupInfo->Title[i])!=0 && i < MAX_PATH)
{
- lpStartupInfo->lpTitle[i] = (unsigned char)pPeb->StartupInfo->Title[i];
+ lpStartupInfo->lpTitle[i] = (char)pPeb->StartupInfo->Title[i];
i++;
}
lpStartupInfo->lpTitle[i] = 0;
return TRUE;
}
-VOID STDCALL ExitProcess(UINT uExitCode)
-{
- NtTerminateProcess(NtCurrentProcess() ,uExitCode);
+VOID
+STDCALL
+ExitProcess(
+ UINT uExitCode
+ )
+{
+
+ NtTerminateProcess(
+ NtCurrentProcess() ,
+ uExitCode
+ );
+
}
VOID
}
+HMODULE
+STDCALL
+GetModuleHandleA(
+ LPCSTR lpModuleName
+ )
+{
+ if ( lpModuleName == NULL )
+ return 0x00010000; // starting address of current module
+ else
+ return NULL; // should return the address of the specified module
+
+ return NULL;
+
+}
+
+HMODULE
+STDCALL
+GetModuleHandleW(
+ LPCWSTR lpModuleName
+ )
+{
+ if ( lpModuleName == NULL )
+ return 0x00010000; // starting address of current module
+ else
+ return NULL; // should return the address of the specified module
+
+ return NULL;
+}
+
+
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS system libraries\r
- * FILE: lib/kernel32/thread/thread.c\r
- * PURPOSE: Thread functions\r
- * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)\r
- Tls functions are modified from WINE\r
- * UPDATE HISTORY:\r
- * Created 01/11/98\r
- */\r
-\r
-#include <windows.h>\r
-#include <kernel32/thread.h>\r
-#include <ddk/ntddk.h>\r
-#include <string.h>\r
-#include <internal/i386/segment.h>\r
-\r
-HANDLE\r
-STDCALL\r
-CreateThread(\r
- LPSECURITY_ATTRIBUTES lpThreadAttributes,\r
- DWORD dwStackSize,\r
- LPTHREAD_START_ROUTINE lpStartAddress,\r
- LPVOID lpParameter,\r
- DWORD dwCreationFlags,\r
- LPDWORD lpThreadId\r
- )\r
-{\r
- return CreateRemoteThread(NtCurrentProcess(),lpThreadAttributes,dwStackSize,\r
- lpStartAddress,lpParameter,dwCreationFlags,lpThreadId);\r
-}\r
-\r
-\r
-\r
-\r
-HANDLE\r
-STDCALL\r
-CreateRemoteThread(\r
- HANDLE hProcess,\r
- LPSECURITY_ATTRIBUTES lpThreadAttributes,\r
- DWORD dwStackSize,\r
- LPTHREAD_START_ROUTINE lpStartAddress,\r
- LPVOID lpParameter,\r
- DWORD dwCreationFlags,\r
- LPDWORD lpThreadId\r
- )\r
-{ \r
- NTSTATUS errCode;\r
- HANDLE ThreadHandle;\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- CLIENT_ID ClientId;\r
- CONTEXT ThreadContext;\r
- INITIAL_TEB InitialTeb;\r
- BOOLEAN CreateSuspended = FALSE;\r
- ULONG BaseAddress;\r
- \r
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);\r
- ObjectAttributes.RootDirectory = NULL;\r
- ObjectAttributes.ObjectName = NULL;\r
- ObjectAttributes.Attributes = 0;\r
- if ( lpThreadAttributes != NULL ) {\r
- if ( lpThreadAttributes->bInheritHandle ) \r
- ObjectAttributes.Attributes = OBJ_INHERIT;\r
- ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;\r
- }\r
- ObjectAttributes.SecurityQualityOfService = NULL;\r
- \r
- if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )\r
- CreateSuspended = TRUE;\r
- else\r
- CreateSuspended = FALSE;\r
-\r
- BaseAddress = 0;\r
- ZwAllocateVirtualMemory(hProcess,\r
- &BaseAddress,\r
- 0,\r
- &dwStackSize,\r
- MEM_COMMIT,\r
- PAGE_READWRITE);\r
- \r
-\r
- memset(&ThreadContext,0,sizeof(CONTEXT));\r
- ThreadContext.Eip = lpStartAddress;\r
- ThreadContext.SegGs = USER_DS;\r
- ThreadContext.SegFs = USER_DS;\r
- ThreadContext.SegEs = USER_DS;\r
- ThreadContext.SegDs = USER_DS;\r
- ThreadContext.SegCs = USER_CS;\r
- ThreadContext.SegSs = USER_DS; \r
- ThreadContext.Esp = BaseAddress + dwStackSize;\r
- ThreadContext.EFlags = (1<<1) + (1<<9);\r
-\r
-\r
- errCode = NtCreateThread(&ThreadHandle,\r
- THREAD_ALL_ACCESS,\r
- &ObjectAttributes,\r
- hProcess,\r
- &ClientId,\r
- &ThreadContext,\r
- &InitialTeb,\r
- CreateSuspended);\r
- if ( lpThreadId != NULL )\r
- memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));\r
- \r
- return ThreadHandle;\r
-}\r
-\r
-NT_TEB *GetTeb(VOID)\r
-{\r
- return NULL;\r
-}\r
-\r
-WINBOOL STDCALL SwitchToThread(VOID )\r
-{\r
- NTSTATUS errCode;\r
- errCode = NtYieldExecution();\r
- return TRUE;\r
-}\r
-\r
-DWORD STDCALL GetCurrentThreadId()\r
-{\r
-\r
- return (DWORD)(GetTeb()->Cid).UniqueThread; \r
-}\r
-\r
-VOID STDCALL ExitThread(UINT uExitCode) \r
-{\r
- NTSTATUS errCode; \r
-\r
- errCode = NtTerminateThread(\r
- NtCurrentThread() ,\r
- uExitCode\r
- );\r
- if ( !NT_SUCCESS(errCode) ) {\r
- SetLastError(RtlNtStatusToDosError(errCode));\r
- }\r
- return;\r
-}\r
-\r
-WINBOOL\r
-STDCALL\r
-GetThreadTimes(\r
- HANDLE hThread,\r
- LPFILETIME lpCreationTime,\r
- LPFILETIME lpExitTime,\r
- LPFILETIME lpKernelTime,\r
- LPFILETIME lpUserTime\r
- )\r
-{\r
- NTSTATUS errCode;\r
- KERNEL_USER_TIMES KernelUserTimes;\r
- ULONG ReturnLength;\r
- errCode = NtQueryInformationThread(hThread,ThreadTimes,&KernelUserTimes,sizeof(KERNEL_USER_TIMES),&ReturnLength);\r
- if ( !NT_SUCCESS(errCode) ) {\r
- SetLastError(RtlNtStatusToDosError(errCode));\r
- return FALSE;\r
- }\r
- memcpy(lpCreationTime, &KernelUserTimes.CreateTime, sizeof(FILETIME));\r
- memcpy(lpExitTime, &KernelUserTimes.ExitTime, sizeof(FILETIME));\r
- memcpy(lpKernelTime, &KernelUserTimes.KernelTime, sizeof(FILETIME));\r
- memcpy(lpUserTime, &KernelUserTimes.UserTime, sizeof(FILETIME));\r
- return TRUE;\r
- \r
-}\r
-\r
-\r
-WINBOOL\r
-STDCALL GetThreadContext(\r
- HANDLE hThread, \r
- LPCONTEXT lpContext \r
- )\r
-{\r
- NTSTATUS errCode;\r
- errCode = NtGetContextThread(hThread,lpContext);\r
- if ( !NT_SUCCESS(errCode) ) {\r
- SetLastError(RtlNtStatusToDosError(errCode));\r
- return FALSE;\r
- }\r
- return TRUE;\r
-}\r
-\r
-WINBOOL\r
-STDCALL\r
-SetThreadContext(\r
- HANDLE hThread, \r
- CONST CONTEXT *lpContext \r
- )\r
-{\r
- NTSTATUS errCode;\r
-\r
- errCode = NtSetContextThread(hThread,(void *)lpContext);\r
- if (!NT_SUCCESS(errCode) ) {\r
- SetLastError(RtlNtStatusToDosError(errCode));\r
- return FALSE;\r
- }\r
- return TRUE;\r
-}\r
-\r
-\r
-\r
-WINBOOL \r
-STDCALL\r
-GetExitCodeThread(\r
- HANDLE hThread, \r
- LPDWORD lpExitCode \r
- )\r
-{\r
- NTSTATUS errCode;\r
- THREAD_BASIC_INFORMATION ThreadBasic;\r
- ULONG DataWritten;\r
- errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);\r
- if ( !NT_SUCCESS(errCode) ) {\r
- SetLastError(RtlNtStatusToDosError(errCode));\r
- return FALSE;\r
- }\r
- memcpy( lpExitCode ,&ThreadBasic.ExitStatus,sizeof(DWORD));\r
- return TRUE;\r
- \r
-}\r
-\r
-\r
-DWORD \r
-STDCALL\r
-ResumeThread(\r
- HANDLE hThread \r
- )\r
-{\r
- NTSTATUS errCode;\r
- ULONG PreviousResumeCount;\r
-\r
- errCode = NtResumeThread(hThread,&PreviousResumeCount );\r
- if ( !NT_SUCCESS(errCode) ) {\r
- SetLastError(RtlNtStatusToDosError(errCode));\r
- return -1;\r
- }\r
- return PreviousResumeCount;\r
-}\r
-\r
-DWORD \r
-STDCALL\r
-SuspendThread(\r
- HANDLE hThread \r
- )\r
-{\r
- NTSTATUS errCode;\r
- ULONG PreviousSuspendCount;\r
-\r
- errCode = NtSuspendThread(hThread,&PreviousSuspendCount );\r
- if ( !NT_SUCCESS(errCode) ) {\r
- SetLastError(RtlNtStatusToDosError(errCode));\r
- return -1;\r
- }\r
- return PreviousSuspendCount;\r
-}\r
-\r
-\r
-DWORD\r
-STDCALL\r
-SetThreadAffinityMask(\r
- HANDLE hThread,\r
- DWORD dwThreadAffinityMask\r
- )\r
-{\r
- return 0;\r
-}\r
-\r
-\r
-WINBOOL\r
-STDCALL\r
-SetThreadPriority(\r
- HANDLE hThread,\r
- int nPriority\r
- )\r
-{\r
- NTSTATUS errCode;\r
- THREAD_BASIC_INFORMATION ThreadBasic;\r
- ULONG DataWritten;\r
- errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);\r
- if ( !NT_SUCCESS(errCode) ) {\r
- SetLastError(RtlNtStatusToDosError(errCode));\r
- return FALSE;\r
- }\r
- ThreadBasic.BasePriority = nPriority;\r
- errCode = NtSetInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION));\r
- if ( !NT_SUCCESS(errCode) ) {\r
- SetLastError(RtlNtStatusToDosError(errCode));\r
- return FALSE;\r
- }\r
- return TRUE;\r
-}\r
-\r
-\r
-int\r
-STDCALL\r
-GetThreadPriority(\r
- HANDLE hThread\r
- )\r
-{\r
- NTSTATUS errCode;\r
- THREAD_BASIC_INFORMATION ThreadBasic;\r
- ULONG DataWritten;\r
- errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);\r
- if ( !NT_SUCCESS(errCode) ) {\r
- SetLastError(RtlNtStatusToDosError(errCode));\r
- return THREAD_PRIORITY_ERROR_RETURN;\r
- }\r
- return ThreadBasic.BasePriority;\r
-}\r
-\r
-\r
-/* (WIN32) Thread Local Storage ******************************************** */\r
-\r
-DWORD STDCALL\r
-TlsAlloc(VOID)\r
-{\r
- DWORD dwTlsIndex = GetTeb()->dwTlsIndex;\r
- \r
-\r
- void **TlsData = GetTeb()->TlsData;\r
- \r
- \r
- if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))\r
- {\r
- TlsData[dwTlsIndex] = NULL;\r
- return (dwTlsIndex++);\r
- }\r
- return (0xFFFFFFFFUL);\r
-}\r
-\r
-WINBOOL STDCALL\r
-TlsFree(DWORD dwTlsIndex)\r
-{\r
- \r
- return (TRUE);\r
-}\r
-\r
-LPVOID STDCALL\r
-TlsGetValue(DWORD dwTlsIndex)\r
-{\r
- \r
- \r
- void **TlsData = GetTeb()->TlsData;\r
-\r
- \r
- if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))\r
- {\r
- \r
- SetLastError(NO_ERROR);\r
- return (TlsData[dwTlsIndex]);\r
- }\r
- SetLastError(1);\r
- return (NULL);\r
-}\r
-\r
-WINBOOL STDCALL\r
-TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)\r
-{\r
- \r
- \r
- void **TlsData = GetTeb()->TlsData;\r
-\r
- \r
- if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))\r
- {\r
- \r
- TlsData[dwTlsIndex] = lpTlsValue;\r
- return (TRUE);\r
- }\r
- return (FALSE);\r
-}\r
-\r
-/*************************************************************/\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/kernel32/thread/thread.c
+ * PURPOSE: Thread functions
+ * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
+ Tls functions are modified from WINE
+ * UPDATE HISTORY:
+ * Created 01/11/98
+ */
+
+#include <windows.h>
+#include <kernel32/thread.h>
+#include <ddk/ntddk.h>
+#include <string.h>
+
+
+HANDLE
+STDCALL
+CreateThread(
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ DWORD dwStackSize,
+ LPTHREAD_START_ROUTINE lpStartAddress,
+ LPVOID lpParameter,
+ DWORD dwCreationFlags,
+ LPDWORD lpThreadId
+ )
+{
+ return CreateRemoteThread(NtCurrentProcess(),lpThreadAttributes,dwStackSize,
+ lpStartAddress,lpParameter,dwCreationFlags,lpThreadId);
+}
+
+
+
+
+HANDLE
+STDCALL
+CreateRemoteThread(
+ HANDLE hProcess,
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ DWORD dwStackSize,
+ LPTHREAD_START_ROUTINE lpStartAddress,
+ LPVOID lpParameter,
+ DWORD dwCreationFlags,
+ LPDWORD lpThreadId
+ )
+{
+ NTSTATUS errCode;
+ HANDLE ThreadHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ CLIENT_ID ClientId;
+ CONTEXT ThreadContext;
+ INITIAL_TEB InitialTeb;
+ BOOLEAN CreateSuspended = FALSE;
+
+ ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+ ObjectAttributes.RootDirectory = NULL;
+ ObjectAttributes.ObjectName = NULL;
+ ObjectAttributes.Attributes = 0;
+ if ( lpThreadAttributes != NULL ) {
+ if ( lpThreadAttributes->bInheritHandle )
+ ObjectAttributes.Attributes = OBJ_INHERIT;
+ ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
+ }
+ ObjectAttributes.SecurityQualityOfService = NULL;
+
+ if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )
+ CreateSuspended = TRUE;
+ else
+ CreateSuspended = FALSE;
+ // fix context
+ GetThreadContext(NtCurrentThread(),&ThreadContext);
+ // fix teb [ stack context ] --> check the image file
+
+ errCode = NtCreateThread(
+ &ThreadHandle,
+ THREAD_ALL_ACCESS,
+ &ObjectAttributes,
+ hProcess,
+ &ClientId,
+ &ThreadContext,
+ &InitialTeb,
+ CreateSuspended
+ );
+ if ( lpThreadId != NULL )
+ memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
+
+ return ThreadHandle;
+}
+
+NT_TEB *GetTeb(VOID)
+{
+ return NULL;
+}
+
+WINBOOL STDCALL
+SwitchToThread(VOID )
+{
+ NTSTATUS errCode;
+ errCode = NtYieldExecution();
+ return TRUE;
+}
+
+DWORD
+STDCALL
+GetCurrentThreadId()
+{
+
+ return (DWORD)(GetTeb()->Cid).UniqueThread;
+}
+
+VOID
+STDCALL
+ExitThread(
+ UINT uExitCode
+ )
+{
+ NTSTATUS errCode;
+
+ errCode = NtTerminateThread(
+ NtCurrentThread() ,
+ uExitCode
+ );
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ }
+ return;
+}
+
+WINBOOL
+STDCALL
+GetThreadTimes(
+ HANDLE hThread,
+ LPFILETIME lpCreationTime,
+ LPFILETIME lpExitTime,
+ LPFILETIME lpKernelTime,
+ LPFILETIME lpUserTime
+ )
+{
+ NTSTATUS errCode;
+ KERNEL_USER_TIMES KernelUserTimes;
+ ULONG ReturnLength;
+ errCode = NtQueryInformationThread(hThread,ThreadTimes,&KernelUserTimes,sizeof(KERNEL_USER_TIMES),&ReturnLength);
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ memcpy(lpCreationTime, &KernelUserTimes.CreateTime, sizeof(FILETIME));
+ memcpy(lpExitTime, &KernelUserTimes.ExitTime, sizeof(FILETIME));
+ memcpy(lpKernelTime, &KernelUserTimes.KernelTime, sizeof(FILETIME));
+ memcpy(lpUserTime, &KernelUserTimes.UserTime, sizeof(FILETIME));
+ return TRUE;
+
+}
+
+
+WINBOOL
+STDCALL GetThreadContext(
+ HANDLE hThread,
+ LPCONTEXT lpContext
+ )
+{
+ NTSTATUS errCode;
+ errCode = NtGetContextThread(hThread,lpContext);
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+WINBOOL
+STDCALL
+SetThreadContext(
+ HANDLE hThread,
+ CONST CONTEXT *lpContext
+ )
+{
+ NTSTATUS errCode;
+
+ errCode = NtSetContextThread(hThread,(void *)lpContext);
+ if (!NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+
+WINBOOL
+STDCALL
+GetExitCodeThread(
+ HANDLE hThread,
+ LPDWORD lpExitCode
+ )
+{
+ NTSTATUS errCode;
+ THREAD_BASIC_INFORMATION ThreadBasic;
+ ULONG DataWritten;
+ errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ memcpy( lpExitCode ,&ThreadBasic.ExitStatus,sizeof(DWORD));
+ return TRUE;
+
+}
+
+
+DWORD
+STDCALL
+ResumeThread(
+ HANDLE hThread
+ )
+{
+ NTSTATUS errCode;
+ ULONG PreviousResumeCount;
+
+ errCode = NtResumeThread(hThread,&PreviousResumeCount );
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return -1;
+ }
+ return PreviousResumeCount;
+}
+
+DWORD
+STDCALL
+SuspendThread(
+ HANDLE hThread
+ )
+{
+ NTSTATUS errCode;
+ ULONG PreviousSuspendCount;
+
+ errCode = NtSuspendThread(hThread,&PreviousSuspendCount );
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return -1;
+ }
+ return PreviousSuspendCount;
+}
+
+
+DWORD
+STDCALL
+SetThreadAffinityMask(
+ HANDLE hThread,
+ DWORD dwThreadAffinityMask
+ )
+{
+ return 0;
+}
+
+
+WINBOOL
+STDCALL
+SetThreadPriority(
+ HANDLE hThread,
+ int nPriority
+ )
+{
+ NTSTATUS errCode;
+ THREAD_BASIC_INFORMATION ThreadBasic;
+ ULONG DataWritten;
+ errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ ThreadBasic.BasePriority = nPriority;
+ errCode = NtSetInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION));
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+int
+STDCALL
+GetThreadPriority(
+ HANDLE hThread
+ )
+{
+ NTSTATUS errCode;
+ THREAD_BASIC_INFORMATION ThreadBasic;
+ ULONG DataWritten;
+ errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
+ if ( !NT_SUCCESS(errCode) ) {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return THREAD_PRIORITY_ERROR_RETURN;
+ }
+ return ThreadBasic.BasePriority;
+}
+
+
+/* (WIN32) Thread Local Storage ******************************************** */
+
+DWORD STDCALL
+TlsAlloc(VOID)
+{
+ DWORD dwTlsIndex = GetTeb()->dwTlsIndex;
+
+
+ void **TlsData = GetTeb()->TlsData;
+
+
+ if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
+ {
+ TlsData[dwTlsIndex] = NULL;
+ return (dwTlsIndex++);
+ }
+ return (0xFFFFFFFFUL);
+}
+
+WINBOOL STDCALL
+TlsFree(DWORD dwTlsIndex)
+{
+
+ return (TRUE);
+}
+
+LPVOID STDCALL
+TlsGetValue(DWORD dwTlsIndex)
+{
+
+
+ void **TlsData = GetTeb()->TlsData;
+
+
+ if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
+ {
+
+ SetLastError(NO_ERROR);
+ return (TlsData[dwTlsIndex]);
+ }
+ SetLastError(1);
+ return (NULL);
+}
+
+WINBOOL STDCALL
+TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
+{
+
+
+ void **TlsData = GetTeb()->TlsData;
+
+
+ if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
+ {
+
+ TlsData[dwTlsIndex] = lpTlsValue;
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*************************************************************/
#endif
-unsigned long wstrlen(PWSTR s)
+size_t wstrlen(const wchar_t *s)
{
return wcslen(s);
}
--- /dev/null
+@echo off
+echo copying latest files to a:...
+copy /Y bootflop.bat a:\autoexec.bat
+copy /Y loaders\dos\loadros.com a:
+copy /Y apps\shell\shell.bin a:
+copy /Y ntoskrnl\kimage.bin a:
+copy /Y services\dd\blue\blues.o a:
+copy /Y services\dd\keyboard\keyboard.o a:
+copy /Y services\dd\ide\ide.o a:
+copy /Y services\fs\vfat\vfatfsd.o a:
+
#
# Select the device drivers and filesystems you want
#
-KERNEL_SERVICES = parallel keyboard null mouse serial sound ide test sdisk \
+KERNEL_SERVICES = parallel keyboard blues null mouse serial sound ide test sdisk \
minix vfat
APPS = hello shell
template: dummy
make -C services/fs/template
-
ide-test: dummy
make -C services/dd/ide-test
keyboard: dummy
make -C services/dd/keyboard
+blues: dummy
+ make -C services/dd/blue
+
mouse: dummy
make -C services/dd/mouse
#
# Select the device drivers and filesystems you want
#
-KERNEL_SERVICES = parallel keyboard null mouse serial sound ide test sdisk \
- minix vfat ext2
+KERNEL_SERVICES = parallel keyboard blues null mouse serial sound ide test sdisk \
+ minix vfat # ext2fs
APPS = hello shell
keyboard: dummy
make -C services/dd/keyboard
+blues: dummy
+ make -C services/dd/blue
+
mouse: dummy
make -C services/dd/mouse
sound: dummy
make -C services/dd/sound
-ext2: dummy
- make -C services/fs/ext2
+ext2fs: dummy
+ make -C services/fs/ext2fs
#
# Kernel loaders
#
#
#
+__putchar
+__goxy
+__wherex
+__wherey
+__getscreensize
free_page
get_dma_page
DbgPrint
printk("%s",string);
}
-static void putchar(char c)
+void __putchar(char c)
/*
* FUNCTION: Writes a character to the console and updates the cursor position
* ARGUMENTS:
while ((*str)!=0)
{
- putchar(*str);
+ __putchar(*str);
str++;
}
while ((*str)!=0)
{
- putchar(*str);
+ __putchar(*str);
str++;
}
cursorx=bp->cursorx;
cursory=bp->cursory;
}
+
+
+void __goxy(unsigned x, unsigned y)
+{
+
+ cursorx = x;
+ cursory = y;
+
+}
+
+unsigned __wherex (void)
+{
+ return cursorx;
+}
+
+
+unsigned __wherey (void)
+{
+ return cursory;
+}
+
+void __getscreensize (unsigned *maxx, unsigned *maxy)
+{
+
+ *maxx = (unsigned)(NR_COLUMNS);
+ *maxy = (unsigned)(NR_ROWS);
+}
FileObject->FileName.Buffer = ExAllocatePool(NonPagedPool,
ObjectAttributes->ObjectName->Length);
FileObject->FileName.Length = ObjectAttributes->ObjectName->Length;
+ FileObject->FileName.MaximumLength =
+ ObjectAttributes->ObjectName->MaximumLength;
RtlCopyUnicodeString(&(FileObject->FileName),
ObjectAttributes->ObjectName);
}
#include <ddk/ntddk.h>
#include <internal/io.h>
-#define NDEBUG
+//#define NDEBUG
#include <internal/debug.h>
/* TYPES *******************************************************************/
STDCALL
NtFsControlFile(
IN HANDLE DeviceHandle,
- IN HANDLE Event OPTIONAL,
+ IN HANDLE EventHandle OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
)
{
return(ZwFsControlFile(DeviceHandle,
- Event,
+ EventHandle,
ApcRoutine,
ApcContext,
IoStatusBlock,
STDCALL
ZwFsControlFile(
IN HANDLE DeviceHandle,
- IN HANDLE Event OPTIONAL,
+ IN HANDLE EventHandle OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG OutputBufferSize
)
{
- UNIMPLEMENTED;
+ NTSTATUS Status = -1;
+ PFILE_OBJECT FileObject;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackPtr;
+ KEVENT Event;
+
+
+ if ( InputBufferSize > 0 ) {
+
+ Status = ObReferenceObjectByHandle(DeviceHandle,
+ FILE_WRITE_DATA|FILE_READ_DATA,
+ NULL,
+ UserMode,
+ (PVOID *) &FileObject,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ KeInitializeEvent(&Event,NotificationEvent,FALSE);
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL,
+ FileObject->DeviceObject,
+ InputBuffer,
+ InputBufferSize,
+ 0,
+ &Event,
+ IoStatusBlock);
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ if ( StackPtr == NULL )
+ return -1;
+ StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
+ StackPtr->FileObject = FileObject;
+ StackPtr->Parameters.Write.Length = InputBufferSize;
+ DPRINT("FileObject->DeviceObject %x\n",FileObject->DeviceObject);
+ Status = IoCallDriver(FileObject->DeviceObject,Irp);
+ if (Status==STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
+ {
+ KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
+ return Irp->IoStatus.Status;
+ }
+ }
+
+ if ( OutputBufferSize > 0 ) {
+ CHECKPOINT;
+ Status = ObReferenceObjectByHandle(DeviceHandle,
+ FILE_WRITE_DATA|FILE_READ_DATA,
+ NULL,
+ UserMode,
+ (PVOID *) &FileObject,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+ CHECKPOINT;
+ KeInitializeEvent(&Event,NotificationEvent,FALSE);
+ CHECKPOINT;
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL,
+ FileObject->DeviceObject,
+ OutputBuffer,
+ OutputBufferSize,
+ 0,
+ &Event,
+ IoStatusBlock);
+ CHECKPOINT;
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ if ( StackPtr == NULL )
+ return -1;
+ StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
+ StackPtr->FileObject = FileObject;
+ StackPtr->Parameters.Read.Length = OutputBufferSize;
+ DPRINT("FileObject->DeviceObject %x\n",FileObject->DeviceObject);
+ Status = IoCallDriver(FileObject->DeviceObject,Irp);
+ if (Status==STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
+ {
+ KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
+ return Irp->IoStatus.Status;
+ }
+ }
+ CHECKPOINT;
+ return(Status);
}
VOID IoInitFileSystemImplementation(VOID)
current_entry = current_entry->Flink;
}
}
-CHECKPOINT;
KeReleaseSpinLock(&FileSystemListLock,oldlvl);
-CHECKPOINT;
return(STATUS_UNRECOGNIZED_VOLUME);
}
return(STATUS_UNSUCCESSFUL);
}
- SymbolicLink->TargetName.Buffer = ExAllocatePool(NonPagedPool,
- ((wstrlen(DeviceName->Buffer)+1)*2));
- SymbolicLink->TargetName.MaximumLength = wstrlen(DeviceName->Buffer);
SymbolicLink->TargetName.Length = 0;
- RtlCopyUnicodeString(&(SymbolicLink->TargetName),DeviceName);
- DPRINT("DeviceName %w\n",SymbolicLink->TargetName.Buffer);
+ SymbolicLink->TargetName.MaximumLength =
+ ((wstrlen(DeviceName->Buffer) + 1) * sizeof(WCHAR));
+ SymbolicLink->TargetName.Buffer = ExAllocatePool(NonPagedPool,
+ SymbolicLink->TargetName.MaximumLength);
+ RtlCopyUnicodeString(&(SymbolicLink->TargetName), DeviceName);
+ DPRINT("DeviceName %w\n", SymbolicLink->TargetName.Buffer);
InitializeObjectAttributes(&(SymbolicLink->Target),
&(SymbolicLink->TargetName),0,NULL,NULL);
DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__);
/*
-
* COPYRIGHT: See COPYING in the top level directory
-
* PROJECT: ReactOS kernel
-
* FILE: ntoskrnl/ke/main.c
-
* PURPOSE: Initalizes the kernel
-
* PROGRAMMER: David Welch (welch@mcmail.com)
-
* UPDATE HISTORY:
-
* 28/05/98: Created
-
*/
-
-
/* INCLUDES *****************************************************************/
-
-
#include <windows.h>
-
-
#include <internal/ntoskrnl.h>
-
#include <internal/version.h>
-
#include <internal/mm.h>
-
#include <internal/string.h>
-
#include <internal/symbol.h>
-
#include <internal/module.h>
-
-
#include <internal/mmhal.h>
-
#include <internal/i386/segment.h>
-
-
#define NDEBUG
-
#include <internal/debug.h>
-
-
/* FUNCTIONS ****************************************************************/
-
-
void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type,
-
unsigned int len)
-
/*
-
* FUNCTION: Sets a hardware breakpoint
-
* ARGUMENTS:
-
* i = breakpoint to set (0 to 3)
-
* addr = linear address to break on
-
* type = Type of access to break on
-
* len = length of the variable to watch
-
* NOTES:
-
* The variable to watch must be aligned to its length (i.e. a dword
-
* breakpoint must be aligned to a dword boundary)
-
*
-
* A fatal exception will be generated on the access to the variable.
-
* It is (at the moment) only really useful for catching undefined
-
* pointers if you know the variable effected but not the buggy
-
* routine.
-
*
-
* FIXME: Extend to call out to kernel debugger on breakpoint
-
* Add support for I/O breakpoints
-
* REFERENCES: See the i386 programmer manual for more details
-
*/
-
{
-
unsigned int mask;
-
-
if (i>3)
-
{
-
printk("Invalid breakpoint index at %s:%d\n",__FILE__,__LINE__);
-
return;
-
}
-
-
/*
-
* Load the linear address
-
*/
-
switch (i)
-
{
-
case 0:
-
__asm("movl %0,%%db0\n\t"
-
: /* no outputs */
-
: "d" (addr));
-
break;
-
-
case 1:
-
__asm__("movl %0,%%db1\n\t"
-
: /* no outputs */
-
: "d" (addr));
-
break;
-
-
case 2:
-
__asm__("movl %0,%%db2\n\t"
-
: /* no outputs */
-
: "d" (addr));
-
break;
-
-
case 3:
-
__asm__("movl %0,%%db3\n\t"
-
: /* no outputs */
-
: "d" (addr));
-
break;
-
}
-
-
/*
-
* Setup mask for dr7
-
*/
-
mask = (len<<(16 + 2 + i*4)) + (type<<(16 + i*4)) + (1<<(i*2));
-
__asm__("movl %%db7,%%eax\n\t"
-
"orl %0,%%eax\n\t"
-
"movl %%eax,%%db7\n\t"
-
: /* no outputs */
-
: "d" (mask)
-
: "ax");
-
}
-
-
extern int edata;
-
extern int end;
-
-
asmlinkage void _main(boot_param* _bp)
-
/*
-
* FUNCTION: Called by the boot loader to start the kernel
-
* ARGUMENTS:
-
* _bp = Pointer to boot parameters initialized by the boot loader
-
* NOTE: The boot parameters are stored in low memory which will become
-
* invalid after the memory managment is initialized so we make a local copy.
-
*/
-
{
-
unsigned int i;
-
unsigned int start;
-
unsigned int start1;
-
boot_param bp;
-
-
memset((void *)&edata,0,((int)&end)-((int)&edata));
-
-
/*
-
* Copy the parameters to a local buffer because lowmem will go away
-
*/
-
memcpy(&bp,_bp,sizeof(boot_param));
-
-
/*
-
* Initalize the console (before printing anything)
-
*/
-
HalInitConsole(&bp);
-
-
DbgPrint("Starting ReactOS "KERNEL_VERSION"\n");
-
-
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
-
if (start < ((int)&end))
-
{
-
DbgPrint("start %x end %x\n",start,(int)&end);
-
DbgPrint("Kernel booted incorrectly, aborting\n");
-
DbgPrint("Reduce the amount of uninitialized data\n");
-
for(;;);
-
}
-
start1 = start+PAGE_ROUND_UP(bp.module_length[1]);
-
-
-
/*
-
* Initalize various critical subsystems
-
*/
-
HalInit(&bp);
-
MmInitialize(&bp);
-
KeInit();
-
ObInit();
-
PsInit();
-
IoInit();
-
+ LdrInitModuleManagement();
-
/*
-
* Initalize services loaded at boot time
-
*/
-
DPRINT("%d files loaded\n",bp.nr_files);
-
-
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
-
start1 = start+PAGE_ROUND_UP(bp.module_length[1]);
-
for (i=1;i<bp.nr_files;i++)
-
{
-
- process_boot_module(start);
-
+ LdrProcessDriver(start);
start=start+PAGE_ROUND_UP(bp.module_length[i]);
-
}
+ /*
+ * Load Auto configured drivers
+ */
+ LdrLoadAutoConfigDrivers();
-
/*
-
* Test various features of the kernel
-
*/
-
TstBegin();
-
-
/*
-
* Enter idle loop
-
*/
-
printk("Finished main()\n");
-
PsTerminateSystemThread(STATUS_SUCCESS);
-
}
#include <ddk/ntddk.h>
-//#define NDEBUG
+#define NDEBUG
#include <internal/debug.h>
/* MACROS ********************************************************************/
/* FORWARD DECLARATIONS ******************************************************/
+NTSTATUS LdrLoadDriver(PUNICODE_STRING Filename);
NTSTATUS LdrProcessDriver(PVOID ModuleLoadBase);
/* PE Driver load support */
/* FUNCTIONS *****************************************************************/
-VOID LdrInitModuleManagment(VOID)
+VOID LdrInitModuleManagement(VOID)
{
ANSI_STRING AnsiString;
RtlAnsiStringToUnicodeString(&ObModuleType->TypeName, &AnsiString, TRUE);
}
+/*
+ * load the auto config drivers.
+ */
+VOID LdrLoadAutoConfigDrivers(VOID)
+{
+ NTSTATUS Status;
+ ANSI_STRING AnsiDriverName;
+ UNICODE_STRING DriverName;
+
+ RtlInitAnsiString(&AnsiDriverName,"\\??\\C:\\reactos\\system\\drivers\\keyboard.o");
+ RtlAnsiStringToUnicodeString(&DriverName, &AnsiDriverName, TRUE);
+ Status = LdrLoadDriver(&DriverName);
+ RtlFreeUnicodeString(&DriverName);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("driver load failed, status;%d(%x)\n", Status, Status);
+ DbgPrintErrorMessage(Status);
+ }
+ RtlInitAnsiString(&AnsiDriverName,"\\??\\C:\\reactos\\system\\drivers\\blues.o");
+ RtlAnsiStringToUnicodeString(&DriverName, &AnsiDriverName, TRUE);
+ Status = LdrLoadDriver(&DriverName);
+ RtlFreeUnicodeString(&DriverName);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("driver load failed, status;%d(%x)\n", Status, Status);
+ DbgPrintErrorMessage(Status);
+ }
+
+}
+
/*
* FUNCTION: Loads a kernel driver
* ARGUMENTS:
-/*\r
- * COPYRIGHT: See COPYING in the top directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: ntoskrnl/mm/virtual.c\r
- * PURPOSE: implementing the Virtualxxx section of the win32 api\r
- * PROGRAMMER: David Welch\r
- * UPDATE HISTORY:\r
- * 09/4/98: Created\r
- * 10/6/98: Corrections from Fatahi (i_fatahi@hotmail.com)\r
- * 30/9/98: Implemented ZwxxxVirtualMemory functions\r
- */\r
- \r
-/* INCLUDE *****************************************************************/\r
-\r
-#include <windows.h>\r
-\r
-#include <internal/i386/segment.h>\r
-#include <internal/mm.h>\r
-#include <internal/mmhal.h>\r
-#include <internal/ob.h>\r
-#include <internal/io.h>\r
-#include <internal/ps.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-/* TYPES *******************************************************************/\r
-\r
-extern unsigned int etext;\r
-extern unsigned int end;\r
-\r
-static MEMORY_AREA* kernel_text_desc = NULL;\r
-static MEMORY_AREA* kernel_data_desc = NULL;\r
-static MEMORY_AREA* kernel_param_desc = NULL;\r
-static MEMORY_AREA* kernel_pool_desc = NULL;\r
-\r
-/* FUNCTIONS ****************************************************************/\r
-\r
-void VirtualInit(boot_param* bp)\r
-/*\r
- * FUNCTION: Intialize the memory areas list\r
- * ARGUMENTS:\r
- * bp = Pointer to the boot parameters\r
- * kernel_len = Length of the kernel\r
- */\r
-{\r
- unsigned int kernel_len = bp->end_mem - bp->start_mem;\r
- PVOID BaseAddress;\r
- ULONG Length;\r
- ULONG ParamLength = kernel_len;\r
- \r
- DPRINT("VirtualInit() %x\n",bp);\r
- \r
- MmInitMemoryAreas();\r
- ExInitNonPagedPool(KERNEL_BASE+ PAGE_ROUND_UP(kernel_len) + PAGESIZE);\r
- \r
- \r
- /*\r
- * Setup the system area descriptor list\r
- */\r
- BaseAddress = (PVOID)KERNEL_BASE;\r
- Length = PAGE_ROUND_UP(((ULONG)&etext)) - KERNEL_BASE;\r
- ParamLength = ParamLength - Length;\r
- MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,\r
- Length,0,&kernel_text_desc);\r
- \r
- Length = PAGE_ROUND_UP(((ULONG)&end)) - PAGE_ROUND_UP(((ULONG)&etext));\r
- ParamLength = ParamLength - Length;\r
- DPRINT("Length %x\n",Length);\r
- BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&etext));\r
- MmCreateMemoryArea(KernelMode,\r
- NULL,\r
- MEMORY_AREA_SYSTEM,\r
- &BaseAddress,\r
- Length,\r
- 0,\r
- &kernel_data_desc);\r
- \r
- \r
- BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&end));\r
- Length = ParamLength;\r
- MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,\r
- Length,0,&kernel_param_desc);\r
- \r
- BaseAddress = (PVOID)(KERNEL_BASE + PAGE_ROUND_UP(kernel_len) + PAGESIZE);\r
- Length = NONPAGED_POOL_SIZE;\r
- MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,\r
- Length,0,&kernel_pool_desc);\r
- \r
-// MmDumpMemoryAreas();\r
- CHECKPOINT;\r
- \r
- MmInitSectionImplementation();\r
-}\r
-\r
-ULONG MmCommitedSectionHandleFault(MEMORY_AREA* MemoryArea, ULONG Address)\r
-{\r
- set_page(Address,0x7,get_free_page());\r
- return(TRUE);\r
-}\r
-\r
-NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)\r
-{\r
- LARGE_INTEGER Offset;\r
- IO_STATUS_BLOCK IoStatus;\r
- \r
- DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",\r
- MemoryArea,Address);\r
- \r
- set_page((DWORD)Address,0x7,get_free_page());\r
- \r
- LARGE_INTEGER_QUAD_PART(Offset) = (Address - MemoryArea->BaseAddress) + \r
- MemoryArea->Data.SectionData.ViewOffset;\r
- \r
- DPRINT("MemoryArea->Data.SectionData.Section->FileObject %x\n",\r
- MemoryArea->Data.SectionData.Section->FileObject);\r
- \r
- if (MemoryArea->Data.SectionData.Section->FileObject == NULL)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- \r
- IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,\r
- (PVOID)Address,\r
- &Offset,\r
- &IoStatus);\r
- \r
- DPRINT("Returning from MmSectionHandleFault()\n");\r
- \r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-asmlinkage int page_fault_handler(unsigned int cs,\r
- unsigned int eip)\r
-/*\r
- * FUNCTION: Handle a page fault\r
- */\r
-{\r
- KPROCESSOR_MODE FaultMode;\r
- MEMORY_AREA* MemoryArea;\r
- KIRQL oldlvl;\r
- ULONG stat;\r
- \r
- /*\r
- * Get the address for the page fault\r
- */\r
- unsigned int cr2;\r
- __asm__("movl %%cr2,%0\n\t" : "=d" (cr2)); \r
- DPRINT("Page fault at address %x with eip %x\n",cr2,eip);\r
-\r
- cr2 = PAGE_ROUND_DOWN(cr2);\r
- \r
- if (KeGetCurrentIrql()!=PASSIVE_LEVEL)\r
- {\r
- DbgPrint("Recursive page fault detected\n");\r
- return(0);\r
-// KeBugCheck(0);\r
- }\r
- \r
- KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);\r
- \r
- /*\r
- * Find the memory area for the faulting address\r
- */\r
- if (cr2>=KERNEL_BASE)\r
- {\r
- /*\r
- * Check permissions\r
- */\r
- if (cs!=KERNEL_CS)\r
- {\r
- printk("%s:%d\n",__FILE__,__LINE__);\r
- return(0);\r
- }\r
- FaultMode = UserMode;\r
- }\r
- else\r
- {\r
- FaultMode = KernelMode;\r
- }\r
- \r
- MemoryArea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(),(PVOID)cr2);\r
- if (MemoryArea==NULL)\r
- {\r
- printk("%s:%d\n",__FILE__,__LINE__);\r
- return(0);\r
- }\r
- \r
- switch (MemoryArea->Type)\r
- {\r
- case MEMORY_AREA_SYSTEM:\r
- stat = 0;\r
- break;\r
- \r
- case MEMORY_AREA_SECTION_VIEW_COMMIT:\r
- if (MmSectionHandleFault(MemoryArea, (PVOID)cr2)==STATUS_SUCCESS)\r
- {\r
- stat=1;\r
- }\r
- else\r
- {\r
- stat = 0;\r
- }\r
- break;\r
- \r
- case MEMORY_AREA_COMMIT:\r
- stat = MmCommitedSectionHandleFault(MemoryArea,cr2);\r
- break;\r
- \r
- default:\r
- stat = 0;\r
- break;\r
- }\r
- if (stat)\r
- {\r
- KeLowerIrql(oldlvl);\r
- }\r
- return(stat);\r
-}\r
-\r
-BOOLEAN MmIsNonPagedSystemAddressValid(PVOID VirtualAddress)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-BOOLEAN MmIsAddressValid(PVOID VirtualAddress)\r
-/*\r
- * FUNCTION: Checks whether the given address is valid for a read or write\r
- * ARGUMENTS:\r
- * VirtualAddress = address to check\r
- * RETURNS: True if the access would be valid\r
- * False if the access would cause a page fault\r
- * NOTES: This function checks whether a byte access to the page would\r
- * succeed. Is this realistic for RISC processors which don't\r
- * allow byte granular access?\r
- */\r
-{\r
- MEMORY_AREA* MemoryArea;\r
- \r
- MemoryArea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(),\r
- VirtualAddress);\r
-\r
- if (MemoryArea == NULL)\r
- {\r
- return(FALSE);\r
- }\r
- return(TRUE);\r
-}\r
-\r
-NTSTATUS\r
-STDCALL\r
-NtAllocateVirtualMemory( \r
- IN HANDLE ProcessHandle,\r
- IN OUT PVOID *BaseAddress,\r
- IN ULONG ZeroBits,\r
- IN OUT PULONG RegionSize,\r
- IN ULONG AllocationType, \r
- IN ULONG Protect\r
- )\r
-{\r
- return(ZwAllocateVirtualMemory(ProcessHandle,\r
- BaseAddress,\r
- ZeroBits,\r
- RegionSize,\r
- AllocationType,\r
- Protect));\r
-}\r
-\r
-NTSTATUS\r
-STDCALL\r
-ZwAllocateVirtualMemory( \r
- IN HANDLE ProcessHandle,\r
- IN OUT PVOID *BaseAddress,\r
- IN ULONG ZeroBits,\r
- IN OUT PULONG RegionSize,\r
- IN ULONG AllocationType, \r
- IN ULONG Protect\r
- )\r
-/*\r
- * FUNCTION: Allocates a block of virtual memory in the process address space\r
- * ARGUMENTS:\r
- * ProcessHandle = The handle of the process which owns the virtual memory\r
- * BaseAddress = A pointer to the virtual memory allocated. If you \r
- * supply a non zero value the system will try to \r
- * allocate the memory at the address supplied. It round \r
- * it down to a multiple of the page size.\r
- * ZeroBits = (OPTIONAL) You can specify the number of high order bits \r
- * that must be zero, ensuring that the memory will be \r
- * allocated at a address below a certain value.\r
- * RegionSize = The number of bytes to allocate\r
- * AllocationType = Indicates the type of virtual memory you like to \r
- * allocated, can be one of the values : MEM_COMMIT, \r
- * MEM_RESERVE, MEM_RESET, MEM_TOP_DOWN\r
- * Protect = Indicates the protection type of the pages allocated, can be\r
- * a combination of PAGE_READONLY, PAGE_READWRITE, \r
- * PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_GUARD, \r
- * PAGE_NOACCESS\r
- * REMARKS:\r
- * This function maps to the win32 VirtualAllocEx. Virtual memory is \r
- * process based so the protocol starts with a ProcessHandle. I \r
- * splitted the functionality of obtaining the actual address and \r
- * specifying the start address in two parameters ( BaseAddress and \r
- * StartAddress ) The NumberOfBytesAllocated specify the range and the \r
- * AllocationType and ProctectionType map to the other two parameters.\r
- * RETURNS: Status\r
- */\r
-{\r
- PEPROCESS Process;\r
- MEMORY_AREA* MemoryArea;\r
- ULONG Type;\r
- NTSTATUS Status;\r
- \r
- DPRINT("ZwAllocateVirtualMemory(ProcessHandle %x, *BaseAddress %x, "\r
- "ZeroBits %d, RegionSize %d, AllocationType %x, Protect %x)\n",\r
- ProcessHandle,*BaseAddress,ZeroBits,*RegionSize,AllocationType,\r
- Protect);\r
- \r
- Status = ObReferenceObjectByHandle(ProcessHandle,\r
- PROCESS_VM_OPERATION,\r
- NULL,\r
- UserMode,\r
- (PVOID*)(&Process),\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- DPRINT("ZwAllocateVirtualMemory() = %x\n",Status);\r
- return(Status);\r
- }\r
- \r
- if (AllocationType & MEM_RESERVE)\r
- {\r
- Type = MEMORY_AREA_RESERVE;\r
- }\r
- else\r
- {\r
- Type = MEMORY_AREA_COMMIT;\r
- }\r
- \r
- if ((*BaseAddress) != 0)\r
- {\r
- MemoryArea = MmOpenMemoryAreaByAddress(Process, *BaseAddress);\r
- \r
- if (MemoryArea != NULL)\r
- {\r
- if (MemoryArea->BaseAddress == (*BaseAddress) &&\r
- MemoryArea->Length == *RegionSize)\r
- {\r
- MemoryArea->Type = Type;\r
- MemoryArea->Attributes =Protect;\r
- DPRINT("*BaseAddress %x\n",*BaseAddress);\r
- return(STATUS_SUCCESS);\r
- }\r
- \r
- MemoryArea = MmSplitMemoryArea(Process,\r
- MemoryArea,\r
- *BaseAddress,\r
- *RegionSize,\r
- Type,\r
- Protect);\r
- DPRINT("*BaseAddress %x\n",*BaseAddress);\r
- return(STATUS_SUCCESS);\r
- }\r
- }\r
- \r
- //FIXME RegionSize should be passed as pointer\r
-\r
-\r
- Status = MmCreateMemoryArea(UserMode,\r
- Process,\r
- Type,\r
- BaseAddress,\r
- *RegionSize,\r
- Protect,\r
- &MemoryArea);\r
- \r
- if (Status != STATUS_SUCCESS)\r
- {\r
- DPRINT("ZwAllocateVirtualMemory() = %x\n",Status);\r
- return(Status);\r
- }\r
- \r
- DPRINT("*BaseAddress %x\n",*BaseAddress);\r
- \r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-NTSTATUS STDCALL NtFlushVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID BaseAddress,\r
- IN ULONG NumberOfBytesToFlush,\r
- OUT PULONG NumberOfBytesFlushed OPTIONAL)\r
-{\r
- return(ZwFlushVirtualMemory(ProcessHandle,\r
- BaseAddress,\r
- NumberOfBytesToFlush,\r
- NumberOfBytesFlushed));\r
-}\r
-\r
-NTSTATUS STDCALL ZwFlushVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID BaseAddress,\r
- IN ULONG NumberOfBytesToFlush,\r
- OUT PULONG NumberOfBytesFlushed OPTIONAL)\r
-\r
-/*\r
- * FUNCTION: Flushes virtual memory to file\r
- * ARGUMENTS:\r
- * ProcessHandle = Points to the process that allocated the virtual \r
- * memory\r
- * BaseAddress = Points to the memory address\r
- * NumberOfBytesToFlush = Limits the range to flush,\r
- * NumberOfBytesFlushed = Actual number of bytes flushed\r
- * RETURNS: Status \r
- */\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtFreeVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID *BaseAddress, \r
- IN PULONG RegionSize, \r
- IN ULONG FreeType)\r
-{\r
- return(ZwFreeVirtualMemory(ProcessHandle,\r
- BaseAddress,\r
- RegionSize,\r
- FreeType));\r
-}\r
-\r
-NTSTATUS STDCALL ZwFreeVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID *BaseAddress, \r
- IN PULONG RegionSize, \r
- IN ULONG FreeType)\r
-\r
-/*\r
- * FUNCTION: Frees a range of virtual memory\r
- * ARGUMENTS:\r
- * ProcessHandle = Points to the process that allocated the virtual \r
- * memory\r
- * BaseAddress = Points to the memory address, rounded down to a \r
- * multiple of the pagesize\r
- * RegionSize = Limits the range to free, rounded up to a multiple of \r
- * the paging size\r
- * FreeType = Can be one of the values: MEM_DECOMMIT, or MEM_RELEASE\r
- * RETURNS: Status \r
- */\r
-{\r
- MEMORY_AREA* MemoryArea;\r
- NTSTATUS Status;\r
- PEPROCESS Process;\r
- \r
- Status = ObReferenceObjectByHandle(ProcessHandle,\r
- PROCESS_VM_OPERATION,\r
- PsProcessType,\r
- UserMode,\r
- (PVOID*)(&Process),\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- DbgPrint("ZwFreeVirtualMemory() = %x\n",Status);\r
- return(Status);\r
- }\r
-\r
- MemoryArea = MmOpenMemoryAreaByAddress(Process,*BaseAddress);\r
- if (MemoryArea == NULL)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- \r
- if (FreeType == MEM_RELEASE)\r
- {\r
- if (MemoryArea->BaseAddress != (*BaseAddress))\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- MmFreeMemoryArea(PsGetCurrentProcess(),\r
- BaseAddress,\r
- 0,\r
- TRUE);\r
- return(STATUS_SUCCESS);\r
- }\r
- \r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtLockVirtualMemory(HANDLE ProcessHandle,\r
- PVOID BaseAddress,\r
- ULONG NumberOfBytesToLock,\r
- PULONG NumberOfBytesLocked)\r
-{\r
- return(ZwLockVirtualMemory(ProcessHandle,\r
- BaseAddress,\r
- NumberOfBytesToLock,\r
- NumberOfBytesLocked));\r
-}\r
-\r
-NTSTATUS STDCALL ZwLockVirtualMemory(HANDLE ProcessHandle,\r
- PVOID BaseAddress,\r
- ULONG NumberOfBytesToLock,\r
- PULONG NumberOfBytesLocked)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtProtectVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID BaseAddress,\r
- IN ULONG NumberOfBytesToProtect,\r
- IN ULONG NewAccessProtection,\r
- OUT PULONG OldAccessProtection)\r
-{\r
- return(ZwProtectVirtualMemory(ProcessHandle,\r
- BaseAddress,\r
- NumberOfBytesToProtect,\r
- NewAccessProtection,\r
- OldAccessProtection));\r
-}\r
-\r
-VOID MmChangeAreaProtection(PEPROCESS Process, \r
- PVOID BaseAddress,\r
- ULONG Length, \r
- ULONG Protect)\r
-{\r
- ULONG i;\r
- \r
- for (i=0; i<(Length/PAGESIZE); i++)\r
- {\r
- if (MmIsPagePresent(Process, BaseAddress + (i*PAGESIZE)))\r
- {\r
- MmSetPageProtect(Process, BaseAddress + (i*PAGESIZE), Protect);\r
- }\r
- }\r
-}\r
-\r
-NTSTATUS STDCALL ZwProtectVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID BaseAddress,\r
- IN ULONG NumberOfBytesToProtect,\r
- IN ULONG NewAccessProtection,\r
- OUT PULONG OldAccessProtection)\r
-{\r
- PMEMORY_AREA MemoryArea;\r
- PEPROCESS Process;\r
- NTSTATUS Status;\r
- \r
- Status = ObReferenceObjectByHandle(ProcessHandle,\r
- PROCESS_VM_OPERATION,\r
- PsProcessType,\r
- UserMode,\r
- (PVOID*)(&Process),\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- DbgPrint("ZwProtectVirtualMemory() = %x\n",Status);\r
- return(Status);\r
- }\r
-\r
- MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);\r
- if (MemoryArea == NULL)\r
- {\r
- DbgPrint("ZwProtectVirtualMemory() = %x\n",STATUS_UNSUCCESSFUL);\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
-\r
- *OldAccessProtection = MemoryArea->Attributes;\r
-\r
- if (MemoryArea->BaseAddress == BaseAddress &&\r
- MemoryArea->Length == NumberOfBytesToProtect)\r
- {\r
- MemoryArea->Attributes = NewAccessProtection; \r
- }\r
- else\r
- {\r
- MemoryArea = MmSplitMemoryArea(Process,\r
- MemoryArea,\r
- BaseAddress,\r
- NumberOfBytesToProtect,\r
- MemoryArea->Type,\r
- NewAccessProtection);\r
- }\r
- MmChangeAreaProtection(Process,BaseAddress,NumberOfBytesToProtect,\r
- NewAccessProtection);\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-NTSTATUS STDCALL NtQueryVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID Address,\r
- IN IN CINT VirtualMemoryInformationClass,\r
- OUT PVOID VirtualMemoryInformation,\r
- IN ULONG Length,\r
- OUT PULONG ResultLength)\r
-{\r
- return(ZwQueryVirtualMemory(ProcessHandle,\r
- Address,\r
- VirtualMemoryInformationClass,\r
- VirtualMemoryInformation,\r
- Length,\r
- ResultLength));\r
-}\r
-\r
-NTSTATUS STDCALL ZwQueryVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID Address,\r
- IN CINT VirtualMemoryInformationClass,\r
- OUT PVOID VirtualMemoryInformation,\r
- IN ULONG Length,\r
- OUT PULONG ResultLength)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtReadVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID BaseAddress,\r
- OUT PVOID Buffer,\r
- IN ULONG NumberOfBytesToRead,\r
- OUT PULONG NumberOfBytesRead)\r
-{\r
- return(ZwReadVirtualMemory(ProcessHandle,\r
- BaseAddress,\r
- Buffer,\r
- NumberOfBytesToRead,\r
- NumberOfBytesRead));\r
-}\r
-\r
-NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID BaseAddress,\r
- OUT PVOID Buffer,\r
- IN ULONG NumberOfBytesToRead,\r
- OUT PULONG NumberOfBytesRead)\r
-{\r
- PEPROCESS Process;\r
- MEMORY_AREA* MemoryArea;\r
- ULONG i;\r
- NTSTATUS Status;\r
- PULONG CurrentEntry;\r
- \r
- Status = ObReferenceObjectByHandle(ProcessHandle,\r
- PROCESS_VM_READ,\r
- NULL,\r
- UserMode,\r
- (PVOID*)(&Process),\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
-\r
- MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);\r
- \r
- if (MemoryArea == NULL)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- if (MemoryArea->Length > NumberOfBytesToRead)\r
- {\r
- NumberOfBytesToRead = MemoryArea->Length;\r
- }\r
- \r
- *NumberOfBytesRead = NumberOfBytesToRead;\r
- \r
- for (i=0; i<(NumberOfBytesToRead/PAGESIZE); i++)\r
- {\r
- CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));\r
- RtlCopyMemory(Buffer + (i*PAGESIZE),\r
- (PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),\r
- PAGESIZE);\r
- \r
- }\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-NTSTATUS STDCALL NtUnlockVirtualMemory(HANDLE ProcessHandle,\r
- PVOID BaseAddress,\r
- ULONG NumberOfBytesToUnlock,\r
- PULONG NumberOfBytesUnlocked OPTIONAL)\r
-{\r
- return(ZwUnlockVirtualMemory(ProcessHandle,\r
- BaseAddress,\r
- NumberOfBytesToUnlock,\r
- NumberOfBytesUnlocked));\r
-}\r
-\r
-NTSTATUS STDCALL ZwUnlockVirtualMemory(HANDLE ProcessHandle,\r
- PVOID BaseAddress,\r
- ULONG NumberOfBytesToUnlock,\r
- PULONG NumberOfBytesUnlocked OPTIONAL)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtWriteVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID BaseAddress,\r
- IN PVOID Buffer,\r
- IN ULONG NumberOfBytesToWrite,\r
- OUT PULONG NumberOfBytesWritten)\r
-{\r
- return(ZwWriteVirtualMemory(ProcessHandle,\r
- BaseAddress,\r
- Buffer,\r
- NumberOfBytesToWrite,\r
- NumberOfBytesWritten));\r
-}\r
-\r
-NTSTATUS STDCALL ZwWriteVirtualMemory(IN HANDLE ProcessHandle,\r
- IN PVOID BaseAddress,\r
- IN PVOID Buffer,\r
- IN ULONG NumberOfBytesToWrite,\r
- OUT PULONG NumberOfBytesWritten)\r
-{\r
- PEPROCESS Process;\r
- MEMORY_AREA* MemoryArea;\r
- ULONG i;\r
- NTSTATUS Status;\r
- PULONG CurrentEntry;\r
- \r
- Status = ObReferenceObjectByHandle(ProcessHandle,\r
- PROCESS_VM_WRITE,\r
- NULL,\r
- UserMode,\r
- (PVOID*)(&Process),\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
-\r
- MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);\r
- \r
- if (MemoryArea == NULL)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- if (MemoryArea->Length > NumberOfBytesToWrite)\r
- {\r
- NumberOfBytesToWrite = MemoryArea->Length;\r
- }\r
- \r
- *NumberOfBytesWritten = NumberOfBytesToWrite;\r
- \r
- for (i=0; i<(NumberOfBytesToWrite/PAGESIZE); i++)\r
- {\r
- CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));\r
- RtlCopyMemory((PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),\r
- Buffer + (i*PAGESIZE),\r
- PAGESIZE);\r
- \r
- }\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
+/*
+ * COPYRIGHT: See COPYING in the top directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/mm/virtual.c
+ * PURPOSE: implementing the Virtualxxx section of the win32 api
+ * PROGRAMMER: David Welch
+ * UPDATE HISTORY:
+ * 09/4/98: Created
+ * 10/6/98: Corrections from Fatahi (i_fatahi@hotmail.com)
+ * 30/9/98: Implemented ZwxxxVirtualMemory functions
+ */
+
+/* INCLUDE *****************************************************************/
+
+#include <windows.h>
+
+#include <internal/i386/segment.h>
+#include <internal/mm.h>
+#include <internal/mmhal.h>
+#include <internal/ob.h>
+#include <internal/io.h>
+#include <internal/ps.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* TYPES *******************************************************************/
+
+extern unsigned int etext;
+extern unsigned int end;
+
+static MEMORY_AREA* kernel_text_desc = NULL;
+static MEMORY_AREA* kernel_data_desc = NULL;
+static MEMORY_AREA* kernel_param_desc = NULL;
+static MEMORY_AREA* kernel_pool_desc = NULL;
+
+/* FUNCTIONS ****************************************************************/
+
+void VirtualInit(boot_param* bp)
+/*
+ * FUNCTION: Intialize the memory areas list
+ * ARGUMENTS:
+ * bp = Pointer to the boot parameters
+ * kernel_len = Length of the kernel
+ */
+{
+ unsigned int kernel_len = bp->end_mem - bp->start_mem;
+ PVOID BaseAddress;
+ ULONG Length;
+ ULONG ParamLength = kernel_len;
+
+ DPRINT("VirtualInit() %x\n",bp);
+
+ MmInitMemoryAreas();
+ ExInitNonPagedPool(KERNEL_BASE+ PAGE_ROUND_UP(kernel_len) + PAGESIZE);
+
+
+ /*
+ * Setup the system area descriptor list
+ */
+ BaseAddress = (PVOID)KERNEL_BASE;
+ Length = PAGE_ROUND_UP(((ULONG)&etext)) - KERNEL_BASE;
+ ParamLength = ParamLength - Length;
+ MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,
+ Length,0,&kernel_text_desc);
+
+ Length = PAGE_ROUND_UP(((ULONG)&end)) - PAGE_ROUND_UP(((ULONG)&etext));
+ ParamLength = ParamLength - Length;
+ DPRINT("Length %x\n",Length);
+ BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&etext));
+ MmCreateMemoryArea(KernelMode,
+ NULL,
+ MEMORY_AREA_SYSTEM,
+ &BaseAddress,
+ Length,
+ 0,
+ &kernel_data_desc);
+
+
+ BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&end));
+ Length = ParamLength;
+ MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,
+ Length,0,&kernel_param_desc);
+
+ BaseAddress = (PVOID)(KERNEL_BASE + PAGE_ROUND_UP(kernel_len) + PAGESIZE);
+ Length = NONPAGED_POOL_SIZE;
+ MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,
+ Length,0,&kernel_pool_desc);
+
+// MmDumpMemoryAreas();
+ CHECKPOINT;
+
+ MmInitSectionImplementation();
+}
+
+ULONG MmCommitedSectionHandleFault(MEMORY_AREA* MemoryArea, ULONG Address)
+{
+ set_page(Address,0x7,get_free_page());
+ return(TRUE);
+}
+
+NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)
+{
+ LARGE_INTEGER Offset;
+ IO_STATUS_BLOCK IoStatus;
+
+ DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
+ MemoryArea,Address);
+
+ set_page((DWORD)Address,0x7,get_free_page());
+
+ LARGE_INTEGER_QUAD_PART(Offset) = (Address - MemoryArea->BaseAddress) +
+ MemoryArea->Data.SectionData.ViewOffset;
+
+ DPRINT("MemoryArea->Data.SectionData.Section->FileObject %x\n",
+ MemoryArea->Data.SectionData.Section->FileObject);
+
+ if (MemoryArea->Data.SectionData.Section->FileObject == NULL)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
+ (PVOID)Address,
+ &Offset,
+ &IoStatus);
+
+ DPRINT("Returning from MmSectionHandleFault()\n");
+
+ return(STATUS_SUCCESS);
+}
+
+asmlinkage int page_fault_handler(unsigned int cs,
+ unsigned int eip)
+/*
+ * FUNCTION: Handle a page fault
+ */
+{
+ KPROCESSOR_MODE FaultMode;
+ MEMORY_AREA* MemoryArea;
+ KIRQL oldlvl;
+ ULONG stat;
+
+ /*
+ * Get the address for the page fault
+ */
+ unsigned int cr2;
+ __asm__("movl %%cr2,%0\n\t" : "=d" (cr2));
+ DPRINT("Page fault at address %x with eip %x\n",cr2,eip);
+
+ cr2 = PAGE_ROUND_DOWN(cr2);
+
+ if (KeGetCurrentIrql()!=PASSIVE_LEVEL)
+ {
+ DbgPrint("Recursive page fault detected\n");
+ return(0);
+// KeBugCheck(0);
+ }
+
+ KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
+
+ /*
+ * Find the memory area for the faulting address
+ */
+ if (cr2>=KERNEL_BASE)
+ {
+ /*
+ * Check permissions
+ */
+ if (cs!=KERNEL_CS)
+ {
+ printk("%s:%d\n",__FILE__,__LINE__);
+ return(0);
+ }
+ FaultMode = UserMode;
+ }
+ else
+ {
+ FaultMode = KernelMode;
+ }
+
+ MemoryArea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(),(PVOID)cr2);
+ if (MemoryArea==NULL)
+ {
+ printk("%s:%d\n",__FILE__,__LINE__);
+ return(0);
+ }
+
+ switch (MemoryArea->Type)
+ {
+ case MEMORY_AREA_SYSTEM:
+ stat = 0;
+ break;
+
+ case MEMORY_AREA_SECTION_VIEW_COMMIT:
+ if (MmSectionHandleFault(MemoryArea, (PVOID)cr2)==STATUS_SUCCESS)
+ {
+ stat=1;
+ }
+ else
+ {
+ stat = 0;
+ }
+ break;
+
+ case MEMORY_AREA_COMMIT:
+ stat = MmCommitedSectionHandleFault(MemoryArea,cr2);
+ break;
+
+ default:
+ stat = 0;
+ break;
+ }
+ if (stat)
+ {
+ KeLowerIrql(oldlvl);
+ }
+ return(stat);
+}
+
+BOOLEAN MmIsNonPagedSystemAddressValid(PVOID VirtualAddress)
+{
+ UNIMPLEMENTED;
+}
+
+BOOLEAN MmIsAddressValid(PVOID VirtualAddress)
+/*
+ * FUNCTION: Checks whether the given address is valid for a read or write
+ * ARGUMENTS:
+ * VirtualAddress = address to check
+ * RETURNS: True if the access would be valid
+ * False if the access would cause a page fault
+ * NOTES: This function checks whether a byte access to the page would
+ * succeed. Is this realistic for RISC processors which don't
+ * allow byte granular access?
+ */
+{
+ MEMORY_AREA* MemoryArea;
+
+ MemoryArea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(),
+ VirtualAddress);
+
+ if (MemoryArea == NULL)
+ {
+ return(FALSE);
+ }
+ return(TRUE);
+}
+
+NTSTATUS
+STDCALL
+NtAllocateVirtualMemory(
+ IN HANDLE ProcessHandle,
+ IN OUT PVOID *BaseAddress,
+ IN ULONG ZeroBits,
+ IN OUT PULONG RegionSize,
+ IN ULONG AllocationType,
+ IN ULONG Protect
+ )
+{
+ return(ZwAllocateVirtualMemory(ProcessHandle,
+ BaseAddress,
+ ZeroBits,
+ RegionSize,
+ AllocationType,
+ Protect));
+}
+
+NTSTATUS
+STDCALL
+ZwAllocateVirtualMemory(
+ IN HANDLE ProcessHandle,
+ IN OUT PVOID *BaseAddress,
+ IN ULONG ZeroBits,
+ IN OUT PULONG RegionSize,
+ IN ULONG AllocationType,
+ IN ULONG Protect
+ )
+/*
+ * FUNCTION: Allocates a block of virtual memory in the process address space
+ * ARGUMENTS:
+ * ProcessHandle = The handle of the process which owns the virtual memory
+ * BaseAddress = A pointer to the virtual memory allocated. If you
+ * supply a non zero value the system will try to
+ * allocate the memory at the address supplied. It round
+ * it down to a multiple of the page size.
+ * ZeroBits = (OPTIONAL) You can specify the number of high order bits
+ * that must be zero, ensuring that the memory will be
+ * allocated at a address below a certain value.
+ * RegionSize = The number of bytes to allocate
+ * AllocationType = Indicates the type of virtual memory you like to
+ * allocated, can be one of the values : MEM_COMMIT,
+ * MEM_RESERVE, MEM_RESET, MEM_TOP_DOWN
+ * Protect = Indicates the protection type of the pages allocated, can be
+ * a combination of PAGE_READONLY, PAGE_READWRITE,
+ * PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_GUARD,
+ * PAGE_NOACCESS
+ * REMARKS:
+ * This function maps to the win32 VirtualAllocEx. Virtual memory is
+ * process based so the protocol starts with a ProcessHandle. I
+ * splitted the functionality of obtaining the actual address and
+ * specifying the start address in two parameters ( BaseAddress and
+ * StartAddress ) The NumberOfBytesAllocated specify the range and the
+ * AllocationType and ProctectionType map to the other two parameters.
+ * RETURNS: Status
+ */
+{
+ PEPROCESS Process;
+ MEMORY_AREA* MemoryArea;
+ ULONG Type;
+ NTSTATUS Status;
+
+ DPRINT("ZwAllocateVirtualMemory(ProcessHandle %x, *BaseAddress %x, "
+ "ZeroBits %d, RegionSize %d, AllocationType %x, Protect %x)\n",
+ ProcessHandle,*BaseAddress,ZeroBits,*RegionSize,AllocationType,
+ Protect);
+
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_VM_OPERATION,
+ NULL,
+ UserMode,
+ (PVOID*)(&Process),
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ DPRINT("ZwAllocateVirtualMemory() = %x\n",Status);
+ return(Status);
+ }
+
+ if (AllocationType & MEM_RESERVE)
+ {
+ Type = MEMORY_AREA_RESERVE;
+ }
+ else
+ {
+ Type = MEMORY_AREA_COMMIT;
+ }
+
+ if ((*BaseAddress) != 0)
+ {
+ MemoryArea = MmOpenMemoryAreaByAddress(Process, *BaseAddress);
+
+ if (MemoryArea != NULL)
+ {
+ if (MemoryArea->BaseAddress == (*BaseAddress) &&
+ MemoryArea->Length == *RegionSize)
+ {
+ MemoryArea->Type = Type;
+ MemoryArea->Attributes =Protect;
+ DPRINT("*BaseAddress %x\n",*BaseAddress);
+ return(STATUS_SUCCESS);
+ }
+
+ MemoryArea = MmSplitMemoryArea(Process,
+ MemoryArea,
+ *BaseAddress,
+ *RegionSize,
+ Type,
+ Protect);
+ DPRINT("*BaseAddress %x\n",*BaseAddress);
+ return(STATUS_SUCCESS);
+ }
+ }
+
+ //FIXME RegionSize should be passed as pointer
+
+
+ Status = MmCreateMemoryArea(UserMode,
+ Process,
+ Type,
+ BaseAddress,
+ *RegionSize,
+ Protect,
+ &MemoryArea);
+
+ if (Status != STATUS_SUCCESS)
+ {
+ DPRINT("ZwAllocateVirtualMemory() = %x\n",Status);
+ return(Status);
+ }
+
+ DPRINT("*BaseAddress %x\n",*BaseAddress);
+
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS STDCALL NtFlushVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ IN ULONG NumberOfBytesToFlush,
+ OUT PULONG NumberOfBytesFlushed OPTIONAL)
+{
+ return(ZwFlushVirtualMemory(ProcessHandle,
+ BaseAddress,
+ NumberOfBytesToFlush,
+ NumberOfBytesFlushed));
+}
+
+NTSTATUS STDCALL ZwFlushVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ IN ULONG NumberOfBytesToFlush,
+ OUT PULONG NumberOfBytesFlushed OPTIONAL)
+
+/*
+ * FUNCTION: Flushes virtual memory to file
+ * ARGUMENTS:
+ * ProcessHandle = Points to the process that allocated the virtual
+ * memory
+ * BaseAddress = Points to the memory address
+ * NumberOfBytesToFlush = Limits the range to flush,
+ * NumberOfBytesFlushed = Actual number of bytes flushed
+ * RETURNS: Status
+ */
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtFreeVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID *BaseAddress,
+ IN PULONG RegionSize,
+ IN ULONG FreeType)
+{
+ return(ZwFreeVirtualMemory(ProcessHandle,
+ BaseAddress,
+ RegionSize,
+ FreeType));
+}
+
+NTSTATUS STDCALL ZwFreeVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID *BaseAddress,
+ IN PULONG RegionSize,
+ IN ULONG FreeType)
+
+/*
+ * FUNCTION: Frees a range of virtual memory
+ * ARGUMENTS:
+ * ProcessHandle = Points to the process that allocated the virtual
+ * memory
+ * BaseAddress = Points to the memory address, rounded down to a
+ * multiple of the pagesize
+ * RegionSize = Limits the range to free, rounded up to a multiple of
+ * the paging size
+ * FreeType = Can be one of the values: MEM_DECOMMIT, or MEM_RELEASE
+ * RETURNS: Status
+ */
+{
+ MEMORY_AREA* MemoryArea;
+ NTSTATUS Status;
+ PEPROCESS Process;
+
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_VM_OPERATION,
+ PsProcessType,
+ UserMode,
+ (PVOID*)(&Process),
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ DbgPrint("ZwFreeVirtualMemory() = %x\n",Status);
+ return(Status);
+ }
+
+ MemoryArea = MmOpenMemoryAreaByAddress(Process,*BaseAddress);
+ if (MemoryArea == NULL)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ if (FreeType == MEM_RELEASE)
+ {
+ if (MemoryArea->BaseAddress != (*BaseAddress))
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ MmFreeMemoryArea(PsGetCurrentProcess(),
+ BaseAddress,
+ 0,
+ TRUE);
+ return(STATUS_SUCCESS);
+ }
+
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtLockVirtualMemory(HANDLE ProcessHandle,
+ PVOID BaseAddress,
+ ULONG NumberOfBytesToLock,
+ PULONG NumberOfBytesLocked)
+{
+ return(ZwLockVirtualMemory(ProcessHandle,
+ BaseAddress,
+ NumberOfBytesToLock,
+ NumberOfBytesLocked));
+}
+
+NTSTATUS STDCALL ZwLockVirtualMemory(HANDLE ProcessHandle,
+ PVOID BaseAddress,
+ ULONG NumberOfBytesToLock,
+ PULONG NumberOfBytesLocked)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtProtectVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ IN ULONG NumberOfBytesToProtect,
+ IN ULONG NewAccessProtection,
+ OUT PULONG OldAccessProtection)
+{
+ return(ZwProtectVirtualMemory(ProcessHandle,
+ BaseAddress,
+ NumberOfBytesToProtect,
+ NewAccessProtection,
+ OldAccessProtection));
+}
+
+VOID MmChangeAreaProtection(PEPROCESS Process,
+ PVOID BaseAddress,
+ ULONG Length,
+ ULONG Protect)
+{
+ ULONG i;
+
+ for (i=0; i<(Length/PAGESIZE); i++)
+ {
+ if (MmIsPagePresent(Process, BaseAddress + (i*PAGESIZE)))
+ {
+ MmSetPageProtect(Process, BaseAddress + (i*PAGESIZE), Protect);
+ }
+ }
+}
+
+NTSTATUS STDCALL ZwProtectVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ IN ULONG NumberOfBytesToProtect,
+ IN ULONG NewAccessProtection,
+ OUT PULONG OldAccessProtection)
+{
+ PMEMORY_AREA MemoryArea;
+ PEPROCESS Process;
+ NTSTATUS Status;
+
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_VM_OPERATION,
+ PsProcessType,
+ UserMode,
+ (PVOID*)(&Process),
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ DbgPrint("ZwProtectVirtualMemory() = %x\n",Status);
+ return(Status);
+ }
+
+ MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);
+ if (MemoryArea == NULL)
+ {
+ DbgPrint("ZwProtectVirtualMemory() = %x\n",STATUS_UNSUCCESSFUL);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ *OldAccessProtection = MemoryArea->Attributes;
+
+ if (MemoryArea->BaseAddress == BaseAddress &&
+ MemoryArea->Length == NumberOfBytesToProtect)
+ {
+ MemoryArea->Attributes = NewAccessProtection;
+ }
+ else
+ {
+ MemoryArea = MmSplitMemoryArea(Process,
+ MemoryArea,
+ BaseAddress,
+ NumberOfBytesToProtect,
+ MemoryArea->Type,
+ NewAccessProtection);
+ }
+ MmChangeAreaProtection(Process,BaseAddress,NumberOfBytesToProtect,
+ NewAccessProtection);
+ return(STATUS_SUCCESS);
+}
+
+
+NTSTATUS STDCALL NtQueryVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID Address,
+ IN IN CINT VirtualMemoryInformationClass,
+ OUT PVOID VirtualMemoryInformation,
+ IN ULONG Length,
+ OUT PULONG ResultLength)
+{
+ return(ZwQueryVirtualMemory(ProcessHandle,
+ Address,
+ VirtualMemoryInformationClass,
+ VirtualMemoryInformation,
+ Length,
+ ResultLength));
+}
+
+NTSTATUS STDCALL ZwQueryVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID Address,
+ IN CINT VirtualMemoryInformationClass,
+ OUT PVOID VirtualMemoryInformation,
+ IN ULONG Length,
+ OUT PULONG ResultLength)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtReadVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ OUT PVOID Buffer,
+ IN ULONG NumberOfBytesToRead,
+ OUT PULONG NumberOfBytesRead)
+{
+ return(ZwReadVirtualMemory(ProcessHandle,
+ BaseAddress,
+ Buffer,
+ NumberOfBytesToRead,
+ NumberOfBytesRead));
+}
+
+NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ OUT PVOID Buffer,
+ IN ULONG NumberOfBytesToRead,
+ OUT PULONG NumberOfBytesRead)
+{
+ PEPROCESS Process;
+ MEMORY_AREA* MemoryArea;
+ ULONG i;
+ NTSTATUS Status;
+ PULONG CurrentEntry;
+
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_VM_READ,
+ NULL,
+ UserMode,
+ (PVOID*)(&Process),
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);
+
+ if (MemoryArea == NULL)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (MemoryArea->Length > NumberOfBytesToRead)
+ {
+ NumberOfBytesToRead = MemoryArea->Length;
+ }
+
+ *NumberOfBytesRead = NumberOfBytesToRead;
+
+ for (i=0; i<(NumberOfBytesToRead/PAGESIZE); i++)
+ {
+ CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));
+ RtlCopyMemory(Buffer + (i*PAGESIZE),
+ (PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),
+ PAGESIZE);
+
+ }
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS STDCALL NtUnlockVirtualMemory(HANDLE ProcessHandle,
+ PVOID BaseAddress,
+ ULONG NumberOfBytesToUnlock,
+ PULONG NumberOfBytesUnlocked OPTIONAL)
+{
+ return(ZwUnlockVirtualMemory(ProcessHandle,
+ BaseAddress,
+ NumberOfBytesToUnlock,
+ NumberOfBytesUnlocked));
+}
+
+NTSTATUS STDCALL ZwUnlockVirtualMemory(HANDLE ProcessHandle,
+ PVOID BaseAddress,
+ ULONG NumberOfBytesToUnlock,
+ PULONG NumberOfBytesUnlocked OPTIONAL)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtWriteVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ IN PVOID Buffer,
+ IN ULONG NumberOfBytesToWrite,
+ OUT PULONG NumberOfBytesWritten)
+{
+ return(ZwWriteVirtualMemory(ProcessHandle,
+ BaseAddress,
+ Buffer,
+ NumberOfBytesToWrite,
+ NumberOfBytesWritten));
+}
+
+NTSTATUS STDCALL ZwWriteVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ IN PVOID Buffer,
+ IN ULONG NumberOfBytesToWrite,
+ OUT PULONG NumberOfBytesWritten)
+{
+ PEPROCESS Process;
+ MEMORY_AREA* MemoryArea;
+ ULONG i;
+ NTSTATUS Status;
+ PULONG CurrentEntry;
+
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_VM_WRITE,
+ NULL,
+ UserMode,
+ (PVOID*)(&Process),
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);
+
+ if (MemoryArea == NULL)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (MemoryArea->Length > NumberOfBytesToWrite)
+ {
+ NumberOfBytesToWrite = MemoryArea->Length;
+ }
+
+ *NumberOfBytesWritten = NumberOfBytesToWrite;
+
+ for (i=0; i<(NumberOfBytesToWrite/PAGESIZE); i++)
+ {
+ CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));
+ RtlCopyMemory((PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),
+ Buffer + (i*PAGESIZE),
+ PAGESIZE);
+
+ }
+ return(STATUS_SUCCESS);
+}
+
+
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: ntoskrnl/ob/namespc.c\r
- * PURPOSE: Manages the system namespace\r
- * PROGRAMMER: David Welch (welch@mcmail.com)\r
- * UPDATE HISTORY:\r
- * 22/05/98: Created\r
- */\r
-\r
-/* INCLUDES ***************************************************************/\r
-\r
-#include <windows.h>\r
-#include <wstring.h>\r
-#include <ddk/ntddk.h>\r
-#include <internal/ob.h>\r
-#include <internal/io.h>\r
-#include <internal/string.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-/* GLOBALS ****************************************************************/\r
-\r
-POBJECT_TYPE ObDirectoryType = NULL;\r
-\r
-static struct\r
-{\r
- OBJECT_HEADER hdr;\r
-// DIRECTORY_OBJECT directory;\r
- LIST_ENTRY head;\r
- KSPIN_LOCK Lock;\r
-} namespc_root = {{0,},};\r
-\r
-/* FUNCTIONS **************************************************************/\r
-\r
-NTSTATUS NtOpenDirectoryObject(PHANDLE DirectoryHandle,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_ATTRIBUTES ObjectAttributes)\r
-{\r
- return(ZwOpenDirectoryObject(DirectoryHandle,\r
- DesiredAccess,\r
- ObjectAttributes));\r
-}\r
-\r
-NTSTATUS ZwOpenDirectoryObject(PHANDLE DirectoryHandle,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_ATTRIBUTES ObjectAttributes)\r
-/*\r
- * FUNCTION: Opens a namespace directory object\r
- * ARGUMENTS:\r
- * DirectoryHandle (OUT) = Variable which receives the directory handle\r
- * DesiredAccess = Desired access to the directory\r
- * ObjectAttributes = Structure describing the directory\r
- * RETURNS: Status\r
- * NOTES: Undocumented\r
- */\r
-{\r
- PVOID Object;\r
- NTSTATUS Status;\r
- PWSTR Ignored;\r
- \r
- *DirectoryHandle = 0;\r
- \r
- Status = ObOpenObjectByName(ObjectAttributes,&Object,&Ignored);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- return(Status);\r
- }\r
- \r
- if (BODY_TO_HEADER(Object)->Type!=OBJTYP_DIRECTORY)\r
- { \r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- \r
- *DirectoryHandle = ObInsertHandle(KeGetCurrentProcess(),Object,\r
- DesiredAccess,FALSE);\r
- CHECKPOINT;\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-NTSTATUS NtQueryDirectoryObject(IN HANDLE DirObjHandle,\r
- OUT POBJDIR_INFORMATION DirObjInformation, \r
- IN ULONG BufferLength, \r
- IN BOOLEAN GetNextIndex, \r
- IN BOOLEAN IgnoreInputIndex, \r
- IN OUT PULONG ObjectIndex,\r
- OUT PULONG DataWritten OPTIONAL)\r
-{\r
- return(ZwQueryDirectoryObject(DirObjHandle,\r
- DirObjInformation,\r
- BufferLength,\r
- GetNextIndex,\r
- IgnoreInputIndex,\r
- ObjectIndex,\r
- DataWritten));\r
-}\r
-\r
-NTSTATUS ZwQueryDirectoryObject(IN HANDLE DirObjHandle,\r
- OUT POBJDIR_INFORMATION DirObjInformation, \r
- IN ULONG BufferLength, \r
- IN BOOLEAN GetNextIndex, \r
- IN BOOLEAN IgnoreInputIndex, \r
- IN OUT PULONG ObjectIndex,\r
- OUT PULONG DataWritten OPTIONAL)\r
-/*\r
- * FUNCTION: Reads information from a namespace directory\r
- * ARGUMENTS:\r
- * DirObjInformation (OUT) = Buffer to hold the data read\r
- * BufferLength = Size of the buffer in bytes\r
- * GetNextIndex = If TRUE then set ObjectIndex to the index of the\r
- * next object\r
- * If FALSE then set ObjectIndex to the number of\r
- * objects in the directory\r
- * IgnoreInputIndex = If TRUE start reading at index 0\r
- * If FALSE start reading at the index specified\r
- * by object index\r
- * ObjectIndex = Zero based index into the directory, interpretation\r
- * depends on IgnoreInputIndex and GetNextIndex\r
- * DataWritten (OUT) = Caller supplied storage for the number of bytes\r
- * written (or NULL)\r
- * RETURNS: Status\r
- */\r
-{\r
- PDIRECTORY_OBJECT dir = NULL;\r
- ULONG EntriesToRead;\r
- PLIST_ENTRY current_entry;\r
- POBJECT_HEADER current;\r
- ULONG i=0;\r
- ULONG EntriesToSkip;\r
- NTSTATUS Status;\r
- \r
- DPRINT("ZwQueryDirectoryObject(DirObjHandle %x)\n",DirObjHandle);\r
- DPRINT("dir %x namespc_root %x\n",dir,HEADER_TO_BODY(&(namespc_root.hdr)));\r
- \r
-// assert_irql(PASSIVE_LEVEL);\r
- \r
- Status = ObReferenceObjectByHandle(DirObjHandle,\r
- DIRECTORY_QUERY,\r
- ObDirectoryType,\r
- UserMode,\r
- (PVOID*)&dir,\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
- \r
- EntriesToRead = BufferLength / sizeof(OBJDIR_INFORMATION);\r
- *DataWritten = 0;\r
- \r
- DPRINT("EntriesToRead %d\n",EntriesToRead);\r
- \r
- current_entry = dir->head.Flink;\r
- \r
- /*\r
- * Optionally, skip over some entries at the start of the directory\r
- */\r
- if (!IgnoreInputIndex)\r
- {\r
- CHECKPOINT;\r
- \r
- EntriesToSkip = *ObjectIndex;\r
- while ( i<EntriesToSkip && current_entry!=NULL)\r
- {\r
- current_entry = current_entry->Flink;\r
- }\r
- }\r
- \r
- DPRINT("DirObjInformation %x\n",DirObjInformation);\r
- \r
- /*\r
- * Read the maximum entries possible into the buffer\r
- */\r
- while ( i<EntriesToRead && current_entry!=(&(dir->head)))\r
- {\r
- current = CONTAINING_RECORD(current_entry,OBJECT_HEADER,Entry);\r
- DPRINT("Scanning %w\n",current->Name.Buffer);\r
- DirObjInformation[i].ObjectName.Buffer = \r
- ExAllocatePool(NonPagedPool,(current->Name.Length+1)*2);\r
- DirObjInformation[i].ObjectName.Length = current->Name.Length;\r
- DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length;\r
- DPRINT("DirObjInformation[i].ObjectName.Buffer %x\n",\r
- DirObjInformation[i].ObjectName.Buffer);\r
- RtlCopyUnicodeString(&DirObjInformation[i].ObjectName,\r
- &(current->Name));\r
- i++;\r
- current_entry = current_entry->Flink;\r
- (*DataWritten) = (*DataWritten) + sizeof(OBJDIR_INFORMATION);\r
- CHECKPOINT;\r
- }\r
- CHECKPOINT;\r
- \r
- /*\r
- * Optionally, count the number of entries in the directory\r
- */\r
- if (GetNextIndex)\r
- {\r
- *ObjectIndex=i;\r
- }\r
- else\r
- {\r
- while ( current_entry!=(&(dir->head)) )\r
- {\r
- current_entry=current_entry->Flink;\r
- i++;\r
- }\r
- *ObjectIndex=i;\r
- }\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-NTSTATUS ObReferenceObjectByName(PUNICODE_STRING ObjectPath,\r
- ULONG Attributes,\r
- PACCESS_STATE PassedAccessState,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_TYPE ObjectType,\r
- KPROCESSOR_MODE AccessMode,\r
- PVOID ParseContext,\r
- PVOID* ObjectPtr)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes,\r
- PVOID* Object, PWSTR* UnparsedSection)\r
-{\r
- NTSTATUS Status;\r
- \r
- DPRINT("ObOpenObjectByName(ObjectAttributes %x, Object %x)\n",\r
- ObjectAttributes,Object);\r
- DPRINT("ObjectAttributes = {ObjectName %x ObjectName->Buffer %w}\n",\r
- ObjectAttributes->ObjectName,ObjectAttributes->ObjectName->Buffer);\r
- DPRINT("ObjectAttributes->ObjectName->Length %d\n",\r
- ObjectAttributes->ObjectName->Length);\r
- \r
- *Object = NULL;\r
- Status = ObLookupObject(ObjectAttributes->RootDirectory, \r
- ObjectAttributes->ObjectName->Buffer, \r
- Object,\r
- UnparsedSection,\r
- ObjectAttributes->Attributes);\r
- DPRINT("*Object %x\n",*Object);\r
- DPRINT("ObjectAttributes->ObjectName->Length %d\n",\r
- ObjectAttributes->ObjectName->Length);\r
- return(Status);\r
-}\r
-\r
-void ObInit(void)\r
-/*\r
- * FUNCTION: Initialize the object manager namespace\r
- */\r
-{\r
- ANSI_STRING AnsiString;\r
- \r
- ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));\r
- \r
- ObDirectoryType->TotalObjects = 0;\r
- ObDirectoryType->TotalHandles = 0;\r
- ObDirectoryType->MaxObjects = ULONG_MAX;\r
- ObDirectoryType->MaxHandles = ULONG_MAX;\r
- ObDirectoryType->PagedPoolCharge = 0;\r
- ObDirectoryType->NonpagedPoolCharge = sizeof(DIRECTORY_OBJECT);\r
- ObDirectoryType->Dump = NULL;\r
- ObDirectoryType->Open = NULL;\r
- ObDirectoryType->Close = NULL;\r
- ObDirectoryType->Delete = NULL;\r
- ObDirectoryType->Parse = NULL;\r
- ObDirectoryType->Security = NULL;\r
- ObDirectoryType->QueryName = NULL;\r
- ObDirectoryType->OkayToClose = NULL;\r
- \r
- RtlInitAnsiString(&AnsiString,"Directory");\r
- RtlAnsiStringToUnicodeString(&ObDirectoryType->TypeName,\r
- &AnsiString,TRUE);\r
- \r
- ObInitializeObjectHeader(ObDirectoryType,NULL,&namespc_root.hdr);\r
- InitializeListHead(&namespc_root.head);\r
-}\r
-\r
-NTSTATUS NtCreateDirectoryObject(PHANDLE DirectoryHandle,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_ATTRIBUTES ObjectAttributes)\r
-{\r
- return(ZwCreateDirectoryObject(DirectoryHandle,\r
- DesiredAccess,\r
- ObjectAttributes));\r
-}\r
-\r
-NTSTATUS ZwCreateDirectoryObject(PHANDLE DirectoryHandle,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_ATTRIBUTES ObjectAttributes)\r
-/*\r
- * FUNCTION: Creates or opens a directory object (a container for other\r
- * objects)\r
- * ARGUMENTS:\r
- * DirectoryHandle (OUT) = Caller supplied storage for the handle\r
- * of the directory\r
- * DesiredAccess = Access desired to the directory\r
- * ObjectAttributes = Object attributes initialized with\r
- * InitializeObjectAttributes\r
- * RETURNS: Status\r
- */\r
-{\r
- PDIRECTORY_OBJECT dir;\r
- \r
- dir = ObGenericCreateObject(DirectoryHandle,DesiredAccess,ObjectAttributes,\r
- ObDirectoryType);\r
- \r
- /*\r
- * Initialize the object body\r
- */\r
- InitializeListHead(&dir->head);\r
- KeInitializeSpinLock(&(dir->Lock));\r
- \r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes,\r
- PUNICODE_STRING ObjectName,\r
- ULONG Attributes,\r
- HANDLE RootDirectory,\r
- PSECURITY_DESCRIPTOR SecurityDescriptor)\r
-/*\r
- * FUNCTION: Sets up a parameter of type OBJECT_ATTRIBUTES for a \r
- * subsequent call to ZwCreateXXX or ZwOpenXXX\r
- * ARGUMENTS:\r
- * InitializedAttributes (OUT) = Caller supplied storage for the\r
- * object attributes\r
- * ObjectName = Full path name for object\r
- * Attributes = Attributes for the object\r
- * RootDirectory = Where the object should be placed or NULL\r
- * SecurityDescriptor = Ignored\r
- * \r
- * NOTE:\r
- * Either ObjectName is a fully qualified pathname or a path relative\r
- * to RootDirectory\r
- */\r
-{\r
- DPRINT("InitializeObjectAttributes(InitializedAttributes %x "\r
- "ObjectName %x Attributes %x RootDirectory %x)\n",\r
- InitializedAttributes,ObjectName,Attributes,RootDirectory);\r
- InitializedAttributes->Length=sizeof(OBJECT_ATTRIBUTES);\r
- InitializedAttributes->RootDirectory=RootDirectory;\r
- InitializedAttributes->ObjectName=ObjectName;\r
- InitializedAttributes->Attributes=Attributes;\r
- InitializedAttributes->SecurityDescriptor=SecurityDescriptor;\r
- InitializedAttributes->SecurityQualityOfService=NULL;\r
-}\r
-\r
-static PVOID ObDirLookup(PDIRECTORY_OBJECT dir, PWSTR name,\r
- ULONG Attributes)\r
-/*\r
- * FUNCTION: Looks up an entry within a namespace directory\r
- * ARGUMENTS:\r
- * dir = Directory to lookup in\r
- * name = Entry name to find\r
- * RETURNS: A pointer to the object body if found\r
- * NULL otherwise\r
- */\r
-{\r
- LIST_ENTRY* current = dir->head.Flink;\r
- POBJECT_HEADER current_obj;\r
- \r
- DPRINT("ObDirLookup(dir %x, name %w)\n",dir,name);\r
- \r
- if (name[0]==0)\r
- {\r
- return(dir);\r
- }\r
- if (name[0]=='.'&&name[1]==0)\r
- {\r
- return(dir);\r
- }\r
- if (name[0]=='.'&&name[1]=='.'&&name[2]==0)\r
- {\r
- return(BODY_TO_HEADER(dir)->Parent);\r
- }\r
- while (current!=(&(dir->head)))\r
- {\r
- current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);\r
- DPRINT("Scanning %w\n",current_obj->Name.Buffer);\r
- if (Attributes & OBJ_CASE_INSENSITIVE)\r
- {\r
- if (wcsicmp(current_obj->Name.Buffer, name)==0)\r
- {\r
- DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));\r
- return(HEADER_TO_BODY(current_obj));\r
- }\r
- }\r
- else\r
- {\r
- if ( wcscmp(current_obj->Name.Buffer, name)==0)\r
- {\r
- DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));\r
- return(HEADER_TO_BODY(current_obj));\r
- }\r
- }\r
- current = current->Flink;\r
- }\r
- DPRINT("%s() = NULL\n",__FUNCTION__);\r
- return(NULL);\r
-}\r
-\r
-VOID ObRemoveEntry(POBJECT_HEADER Header)\r
-{\r
- KIRQL oldlvl;\r
- \r
- DPRINT("ObRemoveEntry(Header %x)\n",Header);\r
- \r
- KeAcquireSpinLock(&(Header->Parent->Lock),&oldlvl);\r
- RemoveEntryList(&(Header->Entry));\r
- KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl);\r
-}\r
-\r
-VOID ObCreateEntry(PDIRECTORY_OBJECT parent,POBJECT_HEADER Object)\r
-/*\r
- * FUNCTION: Add an entry to a namespace directory\r
- * ARGUMENTS:\r
- * parent = directory to add in\r
- * name = Name to give the entry\r
- * Object = Header of the object to add the entry for\r
- */\r
-{\r
- DPRINT("ObjCreateEntry(%x,%x,%x,%w)\n",parent,Object,Object->Name.Buffer,\r
- Object->Name.Buffer);\r
- \r
- /*\r
- * Insert ourselves in our parents list\r
- */\r
- InsertTailList(&parent->head,&Object->Entry);\r
-}\r
-\r
-NTSTATUS ObLookupObject(HANDLE rootdir, PWSTR string, PVOID* Object,\r
- PWSTR* UnparsedSection, ULONG Attributes)\r
-/*\r
- * FUNCTION: Lookup an object within the system namespc\r
- * ARGUMENTS:\r
- * root = Directory to start lookup from\r
- * _string = Pathname to lookup\r
- * RETURNS: On success a pointer to the object body\r
- * On failure NULL\r
- */\r
-{\r
- PWSTR current;\r
- PWSTR next;\r
- PDIRECTORY_OBJECT current_dir = NULL;\r
- NTSTATUS Status;\r
- \r
- DPRINT("ObLookupObject(rootdir %x, string %x, string %w, Object %x, "\r
- "UnparsedSection %x)\n",rootdir,string,string,Object,\r
- UnparsedSection);\r
- \r
- \r
- *UnparsedSection = NULL;\r
- *Object = NULL;\r
- \r
- if (rootdir==NULL)\r
- {\r
- current_dir = HEADER_TO_BODY(&(namespc_root.hdr));\r
- }\r
- else\r
- {\r
- ObReferenceObjectByHandle(rootdir,DIRECTORY_TRAVERSE,NULL,\r
- UserMode,(PVOID*)¤t_dir,NULL);\r
- }\r
- \r
- /*\r
- * Bit of a hack this\r
- */\r
- if (string[0]==0)\r
- {\r
- *Object=current_dir;\r
- return(STATUS_SUCCESS);\r
- }\r
-\r
- if (string[0]!='\\')\r
- {\r
- DbgPrint("(%s:%d) Non absolute pathname passed to %s\n",__FILE__,\r
- __LINE__,__FUNCTION__);\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- \r
- next = &string[0];\r
- current = next+1;\r
- \r
- while (next!=NULL && \r
- BODY_TO_HEADER(current_dir)->ObjectType==ObDirectoryType)\r
- { \r
- *next = '\\';\r
- current = next+1;\r
- next = wcschr(next+1,'\\');\r
- if (next!=NULL)\r
- {\r
- *next=0;\r
- }\r
-\r
- DPRINT("current %w current[5] %x next %x ",current,current[5],next);\r
- if (next!=NULL)\r
- {\r
- DPRINT("(next+1) %w",next+1);\r
- }\r
- DPRINT("\n",0);\r
- \r
- current_dir=(PDIRECTORY_OBJECT)ObDirLookup(current_dir,current,\r
- Attributes);\r
- if (current_dir==NULL)\r
- {\r
- DbgPrint("(%s:%d) Path component %w not found\n",__FILE__,\r
- __LINE__,current);\r
- return(STATUS_UNSUCCESSFUL); \r
- }\r
- \r
- if (BODY_TO_HEADER(current_dir)->ObjectType==IoSymbolicLinkType)\r
- {\r
- current_dir = IoOpenSymlink(current_dir); \r
- }\r
- \r
- }\r
- DPRINT("next %x\n",next);\r
- DPRINT("current %x current %w\n",current,current);\r
- if (next==NULL)\r
- {\r
- if (current_dir==NULL)\r
- {\r
- Status = STATUS_UNSUCCESSFUL;\r
- }\r
- else\r
- {\r
- Status = STATUS_SUCCESS;\r
- }\r
- }\r
- else\r
- {\r
- CHECKPOINT;\r
- *next = '\\';\r
- *UnparsedSection = next;\r
- if (BODY_TO_HEADER(current_dir)->ObjectType == IoDeviceType)\r
- {\r
- Status = STATUS_FS_QUERY_REQUIRED;\r
- }\r
- else\r
- {\r
- Status = STATUS_UNSUCCESSFUL;\r
- } \r
- }\r
- CHECKPOINT;\r
- *Object = current_dir;\r
- DPRINT("(%s:%d) current_dir %x\n",__FILE__,__LINE__,current_dir);\r
-\r
- return(Status);\r
-}\r
- \r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/ob/namespc.c
+ * PURPOSE: Manages the system namespace
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * 22/05/98: Created
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include <windows.h>
+#include <wstring.h>
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <internal/io.h>
+#include <internal/string.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ****************************************************************/
+
+POBJECT_TYPE ObDirectoryType = NULL;
+
+static struct
+{
+ OBJECT_HEADER hdr;
+// DIRECTORY_OBJECT directory;
+ LIST_ENTRY head;
+ KSPIN_LOCK Lock;
+} namespc_root = {{0,},};
+
+/* FUNCTIONS **************************************************************/
+
+NTSTATUS NtOpenDirectoryObject(PHANDLE DirectoryHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes)
+{
+ return(ZwOpenDirectoryObject(DirectoryHandle,
+ DesiredAccess,
+ ObjectAttributes));
+}
+
+NTSTATUS ZwOpenDirectoryObject(PHANDLE DirectoryHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes)
+/*
+ * FUNCTION: Opens a namespace directory object
+ * ARGUMENTS:
+ * DirectoryHandle (OUT) = Variable which receives the directory handle
+ * DesiredAccess = Desired access to the directory
+ * ObjectAttributes = Structure describing the directory
+ * RETURNS: Status
+ * NOTES: Undocumented
+ */
+{
+ PVOID Object;
+ NTSTATUS Status;
+ PWSTR Ignored;
+
+ *DirectoryHandle = 0;
+
+ Status = ObOpenObjectByName(ObjectAttributes,&Object,&Ignored);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+
+ if (BODY_TO_HEADER(Object)->Type!=OBJTYP_DIRECTORY)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ *DirectoryHandle = ObInsertHandle(KeGetCurrentProcess(),Object,
+ DesiredAccess,FALSE);
+ CHECKPOINT;
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS NtQueryDirectoryObject(IN HANDLE DirObjHandle,
+ OUT POBJDIR_INFORMATION DirObjInformation,
+ IN ULONG BufferLength,
+ IN BOOLEAN GetNextIndex,
+ IN BOOLEAN IgnoreInputIndex,
+ IN OUT PULONG ObjectIndex,
+ OUT PULONG DataWritten OPTIONAL)
+{
+ return(ZwQueryDirectoryObject(DirObjHandle,
+ DirObjInformation,
+ BufferLength,
+ GetNextIndex,
+ IgnoreInputIndex,
+ ObjectIndex,
+ DataWritten));
+}
+
+NTSTATUS ZwQueryDirectoryObject(IN HANDLE DirObjHandle,
+ OUT POBJDIR_INFORMATION DirObjInformation,
+ IN ULONG BufferLength,
+ IN BOOLEAN GetNextIndex,
+ IN BOOLEAN IgnoreInputIndex,
+ IN OUT PULONG ObjectIndex,
+ OUT PULONG DataWritten OPTIONAL)
+/*
+ * FUNCTION: Reads information from a namespace directory
+ * ARGUMENTS:
+ * DirObjInformation (OUT) = Buffer to hold the data read
+ * BufferLength = Size of the buffer in bytes
+ * GetNextIndex = If TRUE then set ObjectIndex to the index of the
+ * next object
+ * If FALSE then set ObjectIndex to the number of
+ * objects in the directory
+ * IgnoreInputIndex = If TRUE start reading at index 0
+ * If FALSE start reading at the index specified
+ * by object index
+ * ObjectIndex = Zero based index into the directory, interpretation
+ * depends on IgnoreInputIndex and GetNextIndex
+ * DataWritten (OUT) = Caller supplied storage for the number of bytes
+ * written (or NULL)
+ * RETURNS: Status
+ */
+{
+ PDIRECTORY_OBJECT dir = NULL;
+ ULONG EntriesToRead;
+ PLIST_ENTRY current_entry;
+ POBJECT_HEADER current;
+ ULONG i=0;
+ ULONG EntriesToSkip;
+ NTSTATUS Status;
+
+ DPRINT("ZwQueryDirectoryObject(DirObjHandle %x)\n",DirObjHandle);
+ DPRINT("dir %x namespc_root %x\n",dir,HEADER_TO_BODY(&(namespc_root.hdr)));
+
+// assert_irql(PASSIVE_LEVEL);
+
+ Status = ObReferenceObjectByHandle(DirObjHandle,
+ DIRECTORY_QUERY,
+ ObDirectoryType,
+ UserMode,
+ (PVOID*)&dir,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ EntriesToRead = BufferLength / sizeof(OBJDIR_INFORMATION);
+ *DataWritten = 0;
+
+ DPRINT("EntriesToRead %d\n",EntriesToRead);
+
+ current_entry = dir->head.Flink;
+
+ /*
+ * Optionally, skip over some entries at the start of the directory
+ */
+ if (!IgnoreInputIndex)
+ {
+ CHECKPOINT;
+
+ EntriesToSkip = *ObjectIndex;
+ while ( i<EntriesToSkip && current_entry!=NULL)
+ {
+ current_entry = current_entry->Flink;
+ }
+ }
+
+ DPRINT("DirObjInformation %x\n",DirObjInformation);
+
+ /*
+ * Read the maximum entries possible into the buffer
+ */
+ while ( i<EntriesToRead && current_entry!=(&(dir->head)))
+ {
+ current = CONTAINING_RECORD(current_entry,OBJECT_HEADER,Entry);
+ DPRINT("Scanning %w\n",current->Name.Buffer);
+ DirObjInformation[i].ObjectName.Buffer =
+ ExAllocatePool(NonPagedPool, current->Name.Length + sizeof(WCHAR));
+ DirObjInformation[i].ObjectName.Length = current->Name.Length;
+ DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length + sizeof(WCHAR);
+ DPRINT("DirObjInformation[i].ObjectName.Buffer %x\n",
+ DirObjInformation[i].ObjectName.Buffer);
+ RtlCopyUnicodeString(&DirObjInformation[i].ObjectName,
+ &(current->Name));
+ i++;
+ current_entry = current_entry->Flink;
+ (*DataWritten) = (*DataWritten) + sizeof(OBJDIR_INFORMATION);
+ CHECKPOINT;
+ }
+ CHECKPOINT;
+
+ /*
+ * Optionally, count the number of entries in the directory
+ */
+ if (GetNextIndex)
+ {
+ *ObjectIndex=i;
+ }
+ else
+ {
+ while ( current_entry!=(&(dir->head)) )
+ {
+ current_entry=current_entry->Flink;
+ i++;
+ }
+ *ObjectIndex=i;
+ }
+ return(STATUS_SUCCESS);
+}
+
+
+NTSTATUS ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
+ ULONG Attributes,
+ PACCESS_STATE PassedAccessState,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_TYPE ObjectType,
+ KPROCESSOR_MODE AccessMode,
+ PVOID ParseContext,
+ PVOID* ObjectPtr)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes,
+ PVOID* Object, PWSTR* UnparsedSection)
+{
+ NTSTATUS Status;
+
+ DPRINT("ObOpenObjectByName(ObjectAttributes %x, Object %x)\n",
+ ObjectAttributes,Object);
+ DPRINT("ObjectAttributes = {ObjectName %x ObjectName->Buffer %w}\n",
+ ObjectAttributes->ObjectName,ObjectAttributes->ObjectName->Buffer);
+ DPRINT("ObjectAttributes->ObjectName->Length %d\n",
+ ObjectAttributes->ObjectName->Length);
+
+ *Object = NULL;
+ Status = ObLookupObject(ObjectAttributes->RootDirectory,
+ ObjectAttributes->ObjectName->Buffer,
+ Object,
+ UnparsedSection,
+ ObjectAttributes->Attributes);
+ DPRINT("*Object %x\n",*Object);
+ DPRINT("ObjectAttributes->ObjectName->Length %d\n",
+ ObjectAttributes->ObjectName->Length);
+ return(Status);
+}
+
+void ObInit(void)
+/*
+ * FUNCTION: Initialize the object manager namespace
+ */
+{
+ ANSI_STRING AnsiString;
+
+ ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
+
+ ObDirectoryType->TotalObjects = 0;
+ ObDirectoryType->TotalHandles = 0;
+ ObDirectoryType->MaxObjects = ULONG_MAX;
+ ObDirectoryType->MaxHandles = ULONG_MAX;
+ ObDirectoryType->PagedPoolCharge = 0;
+ ObDirectoryType->NonpagedPoolCharge = sizeof(DIRECTORY_OBJECT);
+ ObDirectoryType->Dump = NULL;
+ ObDirectoryType->Open = NULL;
+ ObDirectoryType->Close = NULL;
+ ObDirectoryType->Delete = NULL;
+ ObDirectoryType->Parse = NULL;
+ ObDirectoryType->Security = NULL;
+ ObDirectoryType->QueryName = NULL;
+ ObDirectoryType->OkayToClose = NULL;
+
+ RtlInitAnsiString(&AnsiString,"Directory");
+ RtlAnsiStringToUnicodeString(&ObDirectoryType->TypeName,
+ &AnsiString,TRUE);
+
+ ObInitializeObjectHeader(ObDirectoryType,NULL,&namespc_root.hdr);
+ InitializeListHead(&namespc_root.head);
+}
+
+NTSTATUS NtCreateDirectoryObject(PHANDLE DirectoryHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes)
+{
+ return(ZwCreateDirectoryObject(DirectoryHandle,
+ DesiredAccess,
+ ObjectAttributes));
+}
+
+NTSTATUS ZwCreateDirectoryObject(PHANDLE DirectoryHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes)
+/*
+ * FUNCTION: Creates or opens a directory object (a container for other
+ * objects)
+ * ARGUMENTS:
+ * DirectoryHandle (OUT) = Caller supplied storage for the handle
+ * of the directory
+ * DesiredAccess = Access desired to the directory
+ * ObjectAttributes = Object attributes initialized with
+ * InitializeObjectAttributes
+ * RETURNS: Status
+ */
+{
+ PDIRECTORY_OBJECT dir;
+
+ dir = ObGenericCreateObject(DirectoryHandle,DesiredAccess,ObjectAttributes,
+ ObDirectoryType);
+
+ /*
+ * Initialize the object body
+ */
+ InitializeListHead(&dir->head);
+ KeInitializeSpinLock(&(dir->Lock));
+
+ return(STATUS_SUCCESS);
+}
+
+VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes,
+ PUNICODE_STRING ObjectName,
+ ULONG Attributes,
+ HANDLE RootDirectory,
+ PSECURITY_DESCRIPTOR SecurityDescriptor)
+/*
+ * FUNCTION: Sets up a parameter of type OBJECT_ATTRIBUTES for a
+ * subsequent call to ZwCreateXXX or ZwOpenXXX
+ * ARGUMENTS:
+ * InitializedAttributes (OUT) = Caller supplied storage for the
+ * object attributes
+ * ObjectName = Full path name for object
+ * Attributes = Attributes for the object
+ * RootDirectory = Where the object should be placed or NULL
+ * SecurityDescriptor = Ignored
+ *
+ * NOTE:
+ * Either ObjectName is a fully qualified pathname or a path relative
+ * to RootDirectory
+ */
+{
+ DPRINT("InitializeObjectAttributes(InitializedAttributes %x "
+ "ObjectName %x Attributes %x RootDirectory %x)\n",
+ InitializedAttributes,ObjectName,Attributes,RootDirectory);
+ InitializedAttributes->Length=sizeof(OBJECT_ATTRIBUTES);
+ InitializedAttributes->RootDirectory=RootDirectory;
+ InitializedAttributes->ObjectName=ObjectName;
+ InitializedAttributes->Attributes=Attributes;
+ InitializedAttributes->SecurityDescriptor=SecurityDescriptor;
+ InitializedAttributes->SecurityQualityOfService=NULL;
+}
+
+static PVOID ObDirLookup(PDIRECTORY_OBJECT dir, PWSTR name,
+ ULONG Attributes)
+/*
+ * FUNCTION: Looks up an entry within a namespace directory
+ * ARGUMENTS:
+ * dir = Directory to lookup in
+ * name = Entry name to find
+ * RETURNS: A pointer to the object body if found
+ * NULL otherwise
+ */
+{
+ LIST_ENTRY* current = dir->head.Flink;
+ POBJECT_HEADER current_obj;
+
+ DPRINT("ObDirLookup(dir %x, name %w)\n",dir,name);
+
+ if (name[0]==0)
+ {
+ return(dir);
+ }
+ if (name[0]=='.'&&name[1]==0)
+ {
+ return(dir);
+ }
+ if (name[0]=='.'&&name[1]=='.'&&name[2]==0)
+ {
+ return(BODY_TO_HEADER(dir)->Parent);
+ }
+ while (current!=(&(dir->head)))
+ {
+ current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
+ DPRINT("Scanning %w\n",current_obj->Name.Buffer);
+ if (Attributes & OBJ_CASE_INSENSITIVE)
+ {
+ if (wcsicmp(current_obj->Name.Buffer, name)==0)
+ {
+ DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
+ return(HEADER_TO_BODY(current_obj));
+ }
+ }
+ else
+ {
+ if ( wcscmp(current_obj->Name.Buffer, name)==0)
+ {
+ DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
+ return(HEADER_TO_BODY(current_obj));
+ }
+ }
+ current = current->Flink;
+ }
+ DPRINT("%s() = NULL\n",__FUNCTION__);
+ return(NULL);
+}
+
+VOID ObRemoveEntry(POBJECT_HEADER Header)
+{
+ KIRQL oldlvl;
+
+ DPRINT("ObRemoveEntry(Header %x)\n",Header);
+
+ KeAcquireSpinLock(&(Header->Parent->Lock),&oldlvl);
+ RemoveEntryList(&(Header->Entry));
+ KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl);
+}
+
+VOID ObCreateEntry(PDIRECTORY_OBJECT parent,POBJECT_HEADER Object)
+/*
+ * FUNCTION: Add an entry to a namespace directory
+ * ARGUMENTS:
+ * parent = directory to add in
+ * name = Name to give the entry
+ * Object = Header of the object to add the entry for
+ */
+{
+ DPRINT("ObjCreateEntry(%x,%x,%x,%w)\n",parent,Object,Object->Name.Buffer,
+ Object->Name.Buffer);
+
+ /*
+ * Insert ourselves in our parents list
+ */
+ InsertTailList(&parent->head,&Object->Entry);
+}
+
+NTSTATUS ObLookupObject(HANDLE rootdir, PWSTR string, PVOID* Object,
+ PWSTR* UnparsedSection, ULONG Attributes)
+/*
+ * FUNCTION: Lookup an object within the system namespc
+ * ARGUMENTS:
+ * root = Directory to start lookup from
+ * _string = Pathname to lookup
+ * RETURNS: On success a pointer to the object body
+ * On failure NULL
+ */
+{
+ PWSTR current;
+ PWSTR next;
+ PDIRECTORY_OBJECT current_dir = NULL;
+ NTSTATUS Status;
+
+ DPRINT("ObLookupObject(rootdir %x, string %x, string %w, Object %x, "
+ "UnparsedSection %x)\n",rootdir,string,string,Object,
+ UnparsedSection);
+
+
+ *UnparsedSection = NULL;
+ *Object = NULL;
+
+ if (rootdir==NULL)
+ {
+ current_dir = HEADER_TO_BODY(&(namespc_root.hdr));
+ }
+ else
+ {
+ ObReferenceObjectByHandle(rootdir,DIRECTORY_TRAVERSE,NULL,
+ UserMode,(PVOID*)¤t_dir,NULL);
+ }
+
+ /*
+ * Bit of a hack this
+ */
+ if (string[0]==0)
+ {
+ *Object=current_dir;
+ return(STATUS_SUCCESS);
+ }
+
+ if (string[0]!='\\')
+ {
+ DbgPrint("(%s:%d) Non absolute pathname passed to %s\n",__FILE__,
+ __LINE__,__FUNCTION__);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ next = &string[0];
+ current = next+1;
+
+ while (next!=NULL &&
+ BODY_TO_HEADER(current_dir)->ObjectType==ObDirectoryType)
+ {
+ *next = '\\';
+ current = next+1;
+ next = wcschr(next+1,'\\');
+ if (next!=NULL)
+ {
+ *next=0;
+ }
+
+ DPRINT("current %w current[5] %x next %x ",current,current[5],next);
+ if (next!=NULL)
+ {
+ DPRINT("(next+1) %w",next+1);
+ }
+ DPRINT("\n",0);
+
+ current_dir=(PDIRECTORY_OBJECT)ObDirLookup(current_dir,current,
+ Attributes);
+ if (current_dir==NULL)
+ {
+ DbgPrint("(%s:%d) Path component %w not found\n",__FILE__,
+ __LINE__,current);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ if (BODY_TO_HEADER(current_dir)->ObjectType==IoSymbolicLinkType)
+ {
+ current_dir = IoOpenSymlink(current_dir);
+ }
+
+ }
+ DPRINT("next %x\n",next);
+ DPRINT("current %x current %w\n",current,current);
+ if (next==NULL)
+ {
+ if (current_dir==NULL)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ else
+ {
+ Status = STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ CHECKPOINT;
+ *next = '\\';
+ *UnparsedSection = next;
+ if (BODY_TO_HEADER(current_dir)->ObjectType == IoDeviceType)
+ {
+ Status = STATUS_FS_QUERY_REQUIRED;
+ }
+ else
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ }
+ CHECKPOINT;
+ *Object = current_dir;
+ DPRINT("(%s:%d) current_dir %x\n",__FILE__,__LINE__,current_dir);
+
+ return(Status);
+}
+
+
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: ntoskrnl/ob/object.c\r
- * PURPOSE: Implements generic object managment functions\r
- * PROGRAMMER: David Welch (welch@mcmail.com)\r
- * UPDATE HISTORY:\r
- * 10/06/98: Created\r
- */\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include <ddk/ntddk.h>\r
-#include <internal/ob.h>\r
-#include <wstring.h>\r
-#include <string.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-/* FUNCTIONS ************************************************************/\r
-\r
-NTSTATUS STDCALL NtSetInformationObject(IN HANDLE ObjectHandle,\r
- IN CINT ObjectInformationClass,\r
- IN PVOID ObjectInformation,\r
- IN ULONG Length)\r
-{\r
- return(ZwSetInformationObject(ObjectHandle,\r
- ObjectInformationClass,\r
- ObjectInformation,\r
- Length));\r
-}\r
-\r
-NTSTATUS STDCALL ZwSetInformationObject(IN HANDLE ObjectHandle,\r
- IN CINT ObjectInformationClass,\r
- IN PVOID ObjectInformation,\r
- IN ULONG Length)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtQueryObject(IN HANDLE ObjectHandle,\r
- IN CINT ObjectInformationClass,\r
- OUT PVOID ObjectInformation,\r
- IN ULONG Length,\r
- OUT PULONG ResultLength)\r
-{\r
- return(ZwQueryObject(ObjectHandle,\r
- ObjectInformationClass,\r
- ObjectInformation,\r
- Length,\r
- ResultLength));\r
-}\r
-\r
-NTSTATUS STDCALL ZwQueryObject(IN HANDLE ObjectHandle,\r
- IN CINT ObjectInformationClass,\r
- OUT PVOID ObjectInformation,\r
- IN ULONG Length,\r
- OUT PULONG ResultLength)\r
-{\r
- UNIMPLEMENTED\r
-}\r
-\r
-NTSTATUS NtMakeTemporaryObject(HANDLE Handle)\r
-{\r
- return(ZwMakeTemporaryObject(Handle));\r
-}\r
-\r
-NTSTATUS ZwMakeTemporaryObject(HANDLE Handle)\r
-{\r
- PVOID Object;\r
- NTSTATUS Status; \r
- POBJECT_HEADER ObjectHeader;\r
- \r
- Status = ObReferenceObjectByHandle(Handle,\r
- 0,\r
- NULL,\r
- KernelMode,\r
- &Object,\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
-\r
- ObjectHeader = BODY_TO_HEADER(Object);\r
- ObjectHeader->Permanent = FALSE;\r
- \r
- ObDereferenceObject(Object);\r
- \r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-PVOID ObGenericCreateObject(PHANDLE Handle,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_ATTRIBUTES ObjectAttributes,\r
- POBJECT_TYPE Type)\r
-/*\r
- * FUNCTION: Creates a new object\r
- */\r
-{\r
- POBJECT_HEADER hdr = NULL;\r
- PWSTR path;\r
- PWSTR name;\r
- PWSTR Ignored;\r
- PULONG addr;\r
- PWSTR Buffer;\r
- \r
- DPRINT("ObGenericCreateObject(Handle %x, DesiredAccess %x,"\r
- "ObjectAttributes %x, Type %x)\n",Handle,DesiredAccess,\r
- ObjectAttributes,Type);\r
- \r
- /*\r
- * Allocate the object body and header\r
- */\r
- hdr=(POBJECT_HEADER)ExAllocatePool(NonPagedPool,OBJECT_ALLOC_SIZE(Type));\r
- DPRINT("OBJECT_ALLOC_SIZE(Type) %d\n",OBJECT_ALLOC_SIZE(Type));\r
- if (hdr==NULL)\r
- {\r
- return(NULL);\r
- }\r
- DPRINT("hdr %x\n",hdr);\r
-\r
-\r
- /*\r
- * If unnamed then initalize\r
- */\r
- if (ObjectAttributes==NULL || ObjectAttributes->ObjectName==NULL)\r
- {\r
- ObInitializeObjectHeader(Type,NULL,hdr);\r
- if (Handle != NULL)\r
- {\r
- *Handle = ObInsertHandle(KeGetCurrentProcess(),\r
- HEADER_TO_BODY(hdr),\r
- DesiredAccess,\r
- FALSE);\r
- }\r
- return(HEADER_TO_BODY(hdr));\r
- }\r
-\r
- \r
- /*\r
- * Copy the object name into a buffer\r
- */\r
-// DbgPrint("ObjectAttributes->ObjectName %x\n",ObjectAttributes->ObjectName);\r
-// DbgPrint("ObjectAttributes->ObjectName->Length %d\n",\r
-// ObjectAttributes->ObjectName->Length);\r
-// DbgPrint("ObjectAttributes->ObjectName->MaximumLength %d\n",\r
-// ObjectAttributes->ObjectName->MaximumLength);\r
- Buffer = ExAllocatePool(NonPagedPool,\r
- ((ObjectAttributes->ObjectName->Length+1)*2)); \r
- if (Buffer==NULL)\r
- {\r
- return(NULL); \r
- }\r
- memcpy(Buffer, ObjectAttributes->ObjectName->Buffer,\r
- (ObjectAttributes->ObjectName->Length+1)*2);\r
- \r
- /*\r
- * Seperate the name into a path and name \r
- */\r
- name = wcsrchr(Buffer,'\\');\r
- if (name==NULL)\r
- {\r
- name=Buffer;\r
- path=NULL;\r
- }\r
- else\r
- {\r
- path=Buffer;\r
- *name=0;\r
- name=name+1;\r
- }\r
- DPRINT("name %w path %w\n",name,path);\r
- \r
- ObLookupObject(ObjectAttributes->RootDirectory,\r
- path,\r
- &hdr->Parent,\r
- &Ignored, \r
- 0L);\r
-\r
- /*\r
- * Initialize the object header\r
- */\r
- ObInitializeObjectHeader(Type,name,hdr);\r
-\r
-\r
- ObCreateEntry(hdr->Parent,hdr);\r
-\r
- DPRINT("Handle %x\n",Handle);\r
- if (Handle != NULL)\r
- {\r
- *Handle = ObInsertHandle(KeGetCurrentProcess(),\r
- HEADER_TO_BODY(hdr),\r
- DesiredAccess,\r
- FALSE);\r
- }\r
- \r
- return(HEADER_TO_BODY(hdr));\r
-}\r
-\r
-VOID ObInitializeObjectHeader(POBJECT_TYPE Type, PWSTR name,\r
- POBJECT_HEADER ObjectHeader)\r
-/*\r
- * FUNCTION: Creates a new object\r
- * ARGUMENT:\r
- * id = Identifier for the type of object\r
- * obj = Pointer to the header of the object\r
- */\r
-{\r
- PWSTR temp_name;\r
- \r
- DPRINT("ObInitializeObjectHeader(id %x name %w obj %x)\n",Type,\r
- name,ObjectHeader);\r
-\r
- ObjectHeader->HandleCount = 1;\r
- ObjectHeader->RefCount = 1;\r
- ObjectHeader->ObjectType = Type;\r
- ObjectHeader->Permanent = FALSE;\r
- if (name==NULL)\r
- {\r
- ObjectHeader->Name.Length=0;\r
- ObjectHeader->Name.Buffer=NULL;\r
- }\r
- else\r
- {\r
- RtlInitUnicodeString(&(ObjectHeader->Name),name);\r
- }\r
-}\r
-\r
-\r
-NTSTATUS ObReferenceObjectByPointer(PVOID ObjectBody,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_TYPE ObjectType,\r
- KPROCESSOR_MODE AccessMode)\r
-/*\r
- * FUNCTION: Increments the pointer reference count for a given object\r
- * ARGUMENTS:\r
- * ObjectBody = Object's body\r
- * DesiredAccess = Desired access to the object\r
- * ObjectType = Points to the object type structure\r
- * AccessMode = Type of access check to perform\r
- * RETURNS: Status\r
- */\r
-{\r
- POBJECT_HEADER Object;\r
-\r
- DPRINT("ObReferenceObjectByPointer(%x)\n",ObjectBody);\r
- \r
- Object = BODY_TO_HEADER(ObjectBody);\r
- Object->RefCount++;\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header)\r
-{\r
- if (Header->RefCount == 0 && Header->HandleCount == 0 &&\r
- !Header->Permanent)\r
- {\r
- if (Header->Name.Buffer != NULL)\r
- {\r
- ObRemoveEntry(Header);\r
- }\r
- ExFreePool(Header);\r
- }\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-VOID ObDereferenceObject(PVOID ObjectBody)\r
-/*\r
- * FUNCTION: Decrements a given object's reference count and performs\r
- * retention checks\r
- * ARGUMENTS:\r
- * ObjectBody = Body of the object\r
- */\r
-{\r
- POBJECT_HEADER Header = BODY_TO_HEADER(ObjectBody);\r
- \r
- DPRINT("ObDeferenceObject(ObjectBody %x) RefCount %d\n",ObjectBody,\r
- Header->RefCount);\r
- \r
- Header->RefCount--;\r
- ObPerformRetentionChecks(Header);\r
-}\r
-\r
-\r
-NTSTATUS NtClose(HANDLE Handle)\r
-{\r
- return(ZwClose(Handle));\r
-}\r
-\r
-NTSTATUS ZwClose(HANDLE Handle)\r
-/*\r
- * FUNCTION: Closes a handle reference to an object\r
- * ARGUMENTS:\r
- * Handle = handle to close\r
- * RETURNS: Status\r
- */\r
-{\r
- PVOID ObjectBody;\r
- POBJECT_HEADER Header;\r
- PHANDLE_REP HandleRep;\r
- \r
- assert_irql(PASSIVE_LEVEL);\r
- \r
- HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);\r
- if (HandleRep == NULL)\r
- {\r
- return(STATUS_INVALID_HANDLE);\r
- } \r
- ObjectBody = HandleRep->ObjectBody;\r
- \r
- HandleRep->ObjectBody = NULL;\r
- \r
- Header = BODY_TO_HEADER(ObjectBody);\r
- \r
- Header->HandleCount--;\r
- ObPerformRetentionChecks(Header);\r
- \r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_TYPE ObjectType,\r
- KPROCESSOR_MODE AccessMode,\r
- PVOID* Object,\r
- POBJECT_HANDLE_INFORMATION \r
- HandleInformationPtr)\r
-/*\r
- * FUNCTION: Increments the reference count for an object and returns a \r
- * pointer to its body\r
- * ARGUMENTS:\r
- * Handle = Handle for the object\r
- * DesiredAccess = Desired access to the object\r
- * ObjectType\r
- * AccessMode \r
- * Object (OUT) = Points to the object body on return\r
- * HandleInformation (OUT) = Contains information about the handle \r
- * on return\r
- * RETURNS: Status\r
- */\r
-{\r
- PHANDLE_REP HandleRep;\r
- POBJECT_HEADER ObjectHeader;\r
- \r
- ASSERT_IRQL(PASSIVE_LEVEL);\r
- \r
- DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "\r
- "ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,\r
- ObjectType,AccessMode,Object);\r
- \r
- if (Handle == NtCurrentProcess())\r
- {\r
- *Object = PsGetCurrentProcess();\r
- return(STATUS_SUCCESS);\r
- }\r
- if (Handle == NtCurrentThread())\r
- {\r
- *Object = PsGetCurrentThread();\r
- return(STATUS_SUCCESS);\r
- }\r
- \r
- HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);\r
- if (HandleRep == NULL || HandleRep->ObjectBody == NULL)\r
- {\r
- return(STATUS_INVALID_HANDLE);\r
- }\r
- \r
- ObjectHeader = BODY_TO_HEADER(HandleRep->ObjectBody);\r
- \r
- if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- } \r
- \r
- if (!(HandleRep->GrantedAccess & DesiredAccess))\r
- {\r
- return(STATUS_ACCESS_DENIED);\r
- }\r
- \r
- ObjectHeader->RefCount++;\r
- \r
- *Object = HandleRep->ObjectBody;\r
- \r
- return(STATUS_SUCCESS);\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/ob/object.c
+ * PURPOSE: Implements generic object managment functions
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * 10/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <wstring.h>
+#include <string.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ************************************************************/
+
+NTSTATUS STDCALL NtSetInformationObject(IN HANDLE ObjectHandle,
+ IN CINT ObjectInformationClass,
+ IN PVOID ObjectInformation,
+ IN ULONG Length)
+{
+ return(ZwSetInformationObject(ObjectHandle,
+ ObjectInformationClass,
+ ObjectInformation,
+ Length));
+}
+
+NTSTATUS STDCALL ZwSetInformationObject(IN HANDLE ObjectHandle,
+ IN CINT ObjectInformationClass,
+ IN PVOID ObjectInformation,
+ IN ULONG Length)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtQueryObject(IN HANDLE ObjectHandle,
+ IN CINT ObjectInformationClass,
+ OUT PVOID ObjectInformation,
+ IN ULONG Length,
+ OUT PULONG ResultLength)
+{
+ return(ZwQueryObject(ObjectHandle,
+ ObjectInformationClass,
+ ObjectInformation,
+ Length,
+ ResultLength));
+}
+
+NTSTATUS STDCALL ZwQueryObject(IN HANDLE ObjectHandle,
+ IN CINT ObjectInformationClass,
+ OUT PVOID ObjectInformation,
+ IN ULONG Length,
+ OUT PULONG ResultLength)
+{
+ UNIMPLEMENTED
+}
+
+NTSTATUS NtMakeTemporaryObject(HANDLE Handle)
+{
+ return(ZwMakeTemporaryObject(Handle));
+}
+
+NTSTATUS ZwMakeTemporaryObject(HANDLE Handle)
+{
+ PVOID Object;
+ NTSTATUS Status;
+ POBJECT_HEADER ObjectHeader;
+
+ Status = ObReferenceObjectByHandle(Handle,
+ 0,
+ NULL,
+ KernelMode,
+ &Object,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ ObjectHeader = BODY_TO_HEADER(Object);
+ ObjectHeader->Permanent = FALSE;
+
+ ObDereferenceObject(Object);
+
+ return(STATUS_SUCCESS);
+}
+
+PVOID ObGenericCreateObject(PHANDLE Handle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ POBJECT_TYPE Type)
+/*
+ * FUNCTION: Creates a new object
+ */
+{
+ POBJECT_HEADER hdr = NULL;
+ PWSTR path;
+ PWSTR name;
+ PWSTR Ignored;
+ PULONG addr;
+ PWSTR Buffer;
+
+ DPRINT("ObGenericCreateObject(Handle %x, DesiredAccess %x,"
+ "ObjectAttributes %x, Type %x)\n",Handle,DesiredAccess,
+ ObjectAttributes,Type);
+
+ /*
+ * Allocate the object body and header
+ */
+ hdr=(POBJECT_HEADER)ExAllocatePool(NonPagedPool,OBJECT_ALLOC_SIZE(Type));
+ DPRINT("OBJECT_ALLOC_SIZE(Type) %d\n",OBJECT_ALLOC_SIZE(Type));
+ if (hdr==NULL)
+ {
+ return(NULL);
+ }
+ DPRINT("hdr %x\n",hdr);
+
+
+ /*
+ * If unnamed then initalize
+ */
+ if (ObjectAttributes==NULL || ObjectAttributes->ObjectName==NULL)
+ {
+ ObInitializeObjectHeader(Type,NULL,hdr);
+ if (Handle != NULL)
+ {
+ *Handle = ObInsertHandle(KeGetCurrentProcess(),
+ HEADER_TO_BODY(hdr),
+ DesiredAccess,
+ FALSE);
+ }
+ return(HEADER_TO_BODY(hdr));
+ }
+
+
+ /*
+ * Copy the object name into a buffer
+ */
+// DbgPrint("ObjectAttributes->ObjectName %x\n",ObjectAttributes->ObjectName);
+// DbgPrint("ObjectAttributes->ObjectName->Length %d\n",
+// ObjectAttributes->ObjectName->Length);
+// DbgPrint("ObjectAttributes->ObjectName->MaximumLength %d\n",
+// ObjectAttributes->ObjectName->MaximumLength);
+ Buffer = ExAllocatePool(NonPagedPool,
+ ((ObjectAttributes->ObjectName->Length + 1) *
+ sizeof(WCHAR)));
+ if (Buffer==NULL)
+ {
+ return(NULL);
+ }
+ memcpy(Buffer, ObjectAttributes->ObjectName->Buffer,
+ (ObjectAttributes->ObjectName->Length + 1) * sizeof(WCHAR));
+
+ /*
+ * Seperate the name into a path and name
+ */
+ name = wcsrchr(Buffer,'\\');
+ if (name==NULL)
+ {
+ name=Buffer;
+ path=NULL;
+ }
+ else
+ {
+ path=Buffer;
+ *name=0;
+ name=name+1;
+ }
+ DPRINT("name %w path %w\n",name,path);
+
+ ObLookupObject(ObjectAttributes->RootDirectory,
+ path,
+ &hdr->Parent,
+ &Ignored,
+ 0L);
+
+ /*
+ * Initialize the object header
+ */
+ ObInitializeObjectHeader(Type,name,hdr);
+
+
+ ObCreateEntry(hdr->Parent,hdr);
+
+ DPRINT("Handle %x\n",Handle);
+ if (Handle != NULL)
+ {
+ *Handle = ObInsertHandle(KeGetCurrentProcess(),
+ HEADER_TO_BODY(hdr),
+ DesiredAccess,
+ FALSE);
+ }
+
+ return(HEADER_TO_BODY(hdr));
+}
+
+VOID ObInitializeObjectHeader(POBJECT_TYPE Type, PWSTR name,
+ POBJECT_HEADER ObjectHeader)
+/*
+ * FUNCTION: Creates a new object
+ * ARGUMENT:
+ * id = Identifier for the type of object
+ * obj = Pointer to the header of the object
+ */
+{
+ PWSTR temp_name;
+
+ DPRINT("ObInitializeObjectHeader(id %x name %w obj %x)\n",Type,
+ name,ObjectHeader);
+
+ ObjectHeader->HandleCount = 1;
+ ObjectHeader->RefCount = 1;
+ ObjectHeader->ObjectType = Type;
+ ObjectHeader->Permanent = FALSE;
+ if (name==NULL)
+ {
+ ObjectHeader->Name.Length=0;
+ ObjectHeader->Name.Buffer=NULL;
+ }
+ else
+ {
+ RtlInitUnicodeString(&(ObjectHeader->Name),name);
+ }
+}
+
+
+NTSTATUS ObReferenceObjectByPointer(PVOID ObjectBody,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_TYPE ObjectType,
+ KPROCESSOR_MODE AccessMode)
+/*
+ * FUNCTION: Increments the pointer reference count for a given object
+ * ARGUMENTS:
+ * ObjectBody = Object's body
+ * DesiredAccess = Desired access to the object
+ * ObjectType = Points to the object type structure
+ * AccessMode = Type of access check to perform
+ * RETURNS: Status
+ */
+{
+ POBJECT_HEADER Object;
+
+ DPRINT("ObReferenceObjectByPointer(%x)\n",ObjectBody);
+
+ Object = BODY_TO_HEADER(ObjectBody);
+ Object->RefCount++;
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header)
+{
+ if (Header->RefCount == 0 && Header->HandleCount == 0 &&
+ !Header->Permanent)
+ {
+ if (Header->Name.Buffer != NULL)
+ {
+ ObRemoveEntry(Header);
+ }
+ ExFreePool(Header);
+ }
+ return(STATUS_SUCCESS);
+}
+
+VOID ObDereferenceObject(PVOID ObjectBody)
+/*
+ * FUNCTION: Decrements a given object's reference count and performs
+ * retention checks
+ * ARGUMENTS:
+ * ObjectBody = Body of the object
+ */
+{
+ POBJECT_HEADER Header = BODY_TO_HEADER(ObjectBody);
+
+ DPRINT("ObDeferenceObject(ObjectBody %x) RefCount %d\n",ObjectBody,
+ Header->RefCount);
+
+ Header->RefCount--;
+ ObPerformRetentionChecks(Header);
+}
+
+
+NTSTATUS NtClose(HANDLE Handle)
+{
+ return(ZwClose(Handle));
+}
+
+NTSTATUS ZwClose(HANDLE Handle)
+/*
+ * FUNCTION: Closes a handle reference to an object
+ * ARGUMENTS:
+ * Handle = handle to close
+ * RETURNS: Status
+ */
+{
+ PVOID ObjectBody;
+ POBJECT_HEADER Header;
+ PHANDLE_REP HandleRep;
+
+ assert_irql(PASSIVE_LEVEL);
+
+ HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);
+ if (HandleRep == NULL)
+ {
+ return(STATUS_INVALID_HANDLE);
+ }
+ ObjectBody = HandleRep->ObjectBody;
+
+ HandleRep->ObjectBody = NULL;
+
+ Header = BODY_TO_HEADER(ObjectBody);
+
+ Header->HandleCount--;
+ ObPerformRetentionChecks(Header);
+
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_TYPE ObjectType,
+ KPROCESSOR_MODE AccessMode,
+ PVOID* Object,
+ POBJECT_HANDLE_INFORMATION
+ HandleInformationPtr)
+/*
+ * FUNCTION: Increments the reference count for an object and returns a
+ * pointer to its body
+ * ARGUMENTS:
+ * Handle = Handle for the object
+ * DesiredAccess = Desired access to the object
+ * ObjectType
+ * AccessMode
+ * Object (OUT) = Points to the object body on return
+ * HandleInformation (OUT) = Contains information about the handle
+ * on return
+ * RETURNS: Status
+ */
+{
+ PHANDLE_REP HandleRep;
+ POBJECT_HEADER ObjectHeader;
+
+ ASSERT_IRQL(PASSIVE_LEVEL);
+
+ DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
+ "ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,
+ ObjectType,AccessMode,Object);
+
+ if (Handle == NtCurrentProcess())
+ {
+ *Object = PsGetCurrentProcess();
+ return(STATUS_SUCCESS);
+ }
+ if (Handle == NtCurrentThread())
+ {
+ *Object = PsGetCurrentThread();
+ return(STATUS_SUCCESS);
+ }
+
+ HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);
+ if (HandleRep == NULL || HandleRep->ObjectBody == NULL)
+ {
+ return(STATUS_INVALID_HANDLE);
+ }
+
+ ObjectHeader = BODY_TO_HEADER(HandleRep->ObjectBody);
+
+ if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ if (!(HandleRep->GrantedAccess & DesiredAccess))
+ {
+ return(STATUS_ACCESS_DENIED);
+ }
+
+ ObjectHeader->RefCount++;
+
+ *Object = HandleRep->ObjectBody;
+
+ return(STATUS_SUCCESS);
+}
+
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: ntoskrnl/ps/process.c\r
- * PURPOSE: Process managment\r
- * PROGRAMMER: David Welch (welch@mcmail.com)\r
- * REVISION HISTORY:\r
- * 21/07/98: Created\r
- */\r
-\r
-/* INCLUDES ******************************************************************/\r
-\r
-#include <ddk/ntddk.h>\r
-#include <internal/ob.h>\r
-#include <internal/mm.h>\r
-#include <internal/string.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-/* GLOBALS ******************************************************************/\r
-\r
-PEPROCESS SystemProcess = NULL;\r
-HANDLE SystemProcessHandle = NULL;\r
-\r
-POBJECT_TYPE PsProcessType = NULL;\r
-\r
-/* FUNCTIONS *****************************************************************/\r
-\r
-VOID PsInitProcessManagment(VOID)\r
-{\r
- ANSI_STRING AnsiString;\r
- PKPROCESS KProcess;\r
- \r
- /*\r
- * Register the process object type\r
- */ \r
- \r
- PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));\r
- \r
- PsProcessType->TotalObjects = 0;\r
- PsProcessType->TotalHandles = 0;\r
- PsProcessType->MaxObjects = ULONG_MAX;\r
- PsProcessType->MaxHandles = ULONG_MAX;\r
- PsProcessType->PagedPoolCharge = 0;\r
- PsProcessType->NonpagedPoolCharge = sizeof(EPROCESS);\r
- PsProcessType->Dump = NULL;\r
- PsProcessType->Open = NULL;\r
- PsProcessType->Close = NULL;\r
- PsProcessType->Delete = NULL;\r
- PsProcessType->Parse = NULL;\r
- PsProcessType->Security = NULL;\r
- PsProcessType->QueryName = NULL;\r
- PsProcessType->OkayToClose = NULL;\r
- \r
- RtlInitAnsiString(&AnsiString,"Process");\r
- RtlAnsiStringToUnicodeString(&PsProcessType->TypeName,&AnsiString,TRUE);\r
- \r
- /*\r
- * Initialize the system process\r
- */\r
- SystemProcess = ObGenericCreateObject(NULL,PROCESS_ALL_ACCESS,NULL,\r
- PsProcessType);\r
- KProcess = &SystemProcess->Pcb; \r
- \r
- InitializeListHead(&(KProcess->MemoryAreaList));\r
- ObInitializeHandleTable(NULL,FALSE,KProcess);\r
- KProcess->PageTableDirectory = get_page_directory();\r
- \r
- SystemProcessHandle = ObInsertHandle(KProcess,SystemProcess,\r
- PROCESS_ALL_ACCESS,FALSE); \r
-}\r
-\r
-PKPROCESS KeGetCurrentProcess(VOID)\r
-/*\r
- * FUNCTION: Returns a pointer to the current process\r
- */\r
-{\r
- return(&(PsGetCurrentProcess()->Pcb));\r
-}\r
-\r
-struct _EPROCESS* PsGetCurrentProcess(VOID)\r
-/*\r
- * FUNCTION: Returns a pointer to the current process\r
- */\r
-{\r
- if (PsGetCurrentThread()==NULL \r
- || PsGetCurrentThread()->ThreadsProcess==NULL)\r
- {\r
- return(SystemProcess);\r
- }\r
- else\r
- {\r
- return(PsGetCurrentThread()->ThreadsProcess);\r
- }\r
-}\r
-\r
-NTSTATUS STDCALL NtCreateProcess(\r
- OUT PHANDLE ProcessHandle,\r
- IN ACCESS_MASK DesiredAccess,\r
- IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\r
- IN HANDLE ParentProcessHandle,\r
- IN BOOLEAN InheritObjectTable,\r
- IN HANDLE SectionHandle OPTIONAL,\r
- IN HANDLE DebugPort OPTIONAL,\r
- IN HANDLE ExceptionPort OPTIONAL)\r
-{\r
- return(ZwCreateProcess(ProcessHandle,\r
- DesiredAccess,\r
- ObjectAttributes,\r
- ParentProcessHandle,\r
- InheritObjectTable,\r
- SectionHandle,\r
- DebugPort,\r
- ExceptionPort));\r
-}\r
-\r
-NTSTATUS STDCALL ZwCreateProcess(\r
- OUT PHANDLE ProcessHandle,\r
- IN ACCESS_MASK DesiredAccess,\r
- IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\r
- IN HANDLE ParentProcessHandle,\r
- IN BOOLEAN InheritObjectTable,\r
- IN HANDLE SectionHandle OPTIONAL,\r
- IN HANDLE DebugPort OPTIONAL,\r
- IN HANDLE ExceptionPort OPTIONAL)\r
-/*\r
- * FUNCTION: Creates a process.\r
- * ARGUMENTS:\r
- * ProcessHandle (OUT) = Caller supplied storage for the resulting \r
- * handle\r
- * DesiredAccess = Specifies the allowed or desired access to the \r
- * process can be a combination of \r
- * STANDARD_RIGHTS_REQUIRED| .. \r
- * ObjectAttribute = Initialized attributes for the object, contains \r
- * the rootdirectory and the filename\r
- * ParentProcess = Handle to the parent process.\r
- * InheritObjectTable = Specifies to inherit the objects of the parent \r
- * process if true.\r
- * SectionHandle = Handle to a section object to back the image file\r
- * DebugPort = Handle to a DebugPort if NULL the system default debug \r
- * port will be used.\r
- * ExceptionPort = Handle to a exception port. \r
- * REMARKS:\r
- * This function maps to the win32 CreateProcess. \r
- * RETURNS: Status\r
- */\r
-{\r
- PEPROCESS Process;\r
- PEPROCESS ParentProcess;\r
- PULONG PageDirectory;\r
- PULONG CurrentPageDirectory;\r
- ULONG i;\r
- PKPROCESS KProcess;\r
- ULONG Base;\r
- ULONG Length;\r
- LARGE_INTEGER Offset;\r
- NTSTATUS Status;\r
- \r
- DPRINT("ZwCreateProcess(ObjectAttributes %x)\n",ObjectAttributes);\r
-\r
- Status = ObReferenceObjectByHandle(ParentProcessHandle,\r
- PROCESS_CREATE_PROCESS,\r
- PsProcessType,\r
- UserMode,\r
- &ParentProcessHandle,\r
- NULL);\r
-\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- DPRINT("ZwCreateProcess() = %x\n",Status);\r
- return(Status);\r
- }\r
-\r
- Process = ObGenericCreateObject(ProcessHandle,\r
- DesiredAccess,\r
- ObjectAttributes,\r
- PsProcessType);\r
- KeInitializeDispatcherHeader(&Process->Pcb.DispatcherHeader,\r
- 0,\r
- sizeof(EPROCESS),\r
- FALSE);\r
- KProcess = &(Process->Pcb);\r
- \r
- InitializeListHead(&(KProcess->MemoryAreaList));\r
- ObInitializeHandleTable(KProcess,InheritObjectTable,KProcess);\r
- \r
- PageDirectory = physical_to_linear((ULONG)get_free_page());\r
- KProcess->PageTableDirectory = PageDirectory;\r
- \r
- CurrentPageDirectory = get_page_directory();\r
- \r
- memset(PageDirectory,0,PAGESIZE);\r
- for (i=768;i<1024;i++)\r
- {\r
- PageDirectory[i]=CurrentPageDirectory[i];\r
- }\r
- \r
- /*\r
- * FIXME: I don't what I'm supposed to know with a section handle\r
- */\r
- if (SectionHandle != NULL)\r
- {\r
- DbgPrint("ZwCreateProcess() non-NULL SectionHandle\n");\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
-\r
- Process->Pcb.ProcessState = PROCESS_STATE_ACTIVE;\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-NTSTATUS STDCALL NtOpenProcess (OUT PHANDLE ProcessHandle,\r
- IN ACCESS_MASK DesiredAccess,\r
- IN POBJECT_ATTRIBUTES ObjectAttributes,\r
- IN PCLIENT_ID ClientId)\r
-{\r
- return(ZwOpenProcess(ProcessHandle,\r
- DesiredAccess,\r
- ObjectAttributes,\r
- ClientId));\r
-}\r
-\r
-NTSTATUS STDCALL ZwOpenProcess (OUT PHANDLE ProcessHandle,\r
- IN ACCESS_MASK DesiredAccess,\r
- IN POBJECT_ATTRIBUTES ObjectAttributes,\r
- IN PCLIENT_ID ClientId)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtQueryInformationProcess(IN HANDLE ProcessHandle,\r
- IN CINT ProcessInformationClass,\r
- OUT PVOID ProcessInformation,\r
- IN ULONG ProcessInformationLength,\r
- OUT PULONG ReturnLength)\r
-{\r
- return(ZwQueryInformationProcess(ProcessHandle,\r
- ProcessInformationClass,\r
- ProcessInformation,\r
- ProcessInformationLength,\r
- ReturnLength));\r
-}\r
-\r
-NTSTATUS STDCALL ZwQueryInformationProcess(IN HANDLE ProcessHandle,\r
- IN CINT ProcessInformationClass,\r
- OUT PVOID ProcessInformation,\r
- IN ULONG ProcessInformationLength,\r
- OUT PULONG ReturnLength)\r
-{\r
- PEPROCESS Process;\r
- NTSTATUS Status;\r
- \r
- Status = ObReferenceObjectByHandle(ProcessHandle,\r
- PROCESS_QUERY_INFORMATION,\r
- PsProcessType,\r
- UserMode,\r
- &ProcessHandle,\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
- \r
- switch (ProcessInformationClass)\r
- {\r
- case ProcessBasicInformation:\r
- case ProcessQuotaLimits:\r
- case ProcessIoCounters:\r
- case ProcessVmCounters:\r
- case ProcessTimes:\r
- case ProcessBasePriority:\r
- case ProcessRaisePriority:\r
- case ProcessDebugPort:\r
- case ProcessExceptionPort:\r
- case ProcessAccessToken:\r
- case ProcessLdtInformation:\r
- case ProcessLdtSize:\r
- case ProcessDefaultHardErrorMode:\r
- case ProcessIoPortHandlers:\r
- case ProcessWorkingSetWatch:\r
- case ProcessUserModeIOPL:\r
- case ProcessEnableAlignmentFaultFixup:\r
- case ProcessPriorityClass:\r
- case ProcessWx86Information:\r
- case ProcessHandleCount:\r
- case ProcessAffinityMask:\r
- default:\r
- Status = STATUS_NOT_IMPLEMENTED;\r
- }\r
- return(Status);\r
-}\r
-\r
-NTSTATUS STDCALL NtSetInformationProcess(IN HANDLE ProcessHandle,\r
- IN CINT ProcessInformationClass,\r
- IN PVOID ProcessInformation,\r
- IN ULONG ProcessInformationLength)\r
-{\r
- return(ZwSetInformationProcess(ProcessHandle,\r
- ProcessInformationClass,\r
- ProcessInformation,\r
- ProcessInformationLength));\r
-}\r
-\r
-NTSTATUS STDCALL ZwSetInformationProcess(IN HANDLE ProcessHandle,\r
- IN CINT ProcessInformationClass,\r
- IN PVOID ProcessInformation,\r
- IN ULONG ProcessInformationLength)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/ps/process.c
+ * PURPOSE: Process managment
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * REVISION HISTORY:
+ * 21/07/98: Created
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <internal/mm.h>
+#include <internal/string.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/
+
+PEPROCESS SystemProcess = NULL;
+HANDLE SystemProcessHandle = NULL;
+
+POBJECT_TYPE PsProcessType = NULL;
+
+/* FUNCTIONS *****************************************************************/
+
+VOID PsInitProcessManagment(VOID)
+{
+ ANSI_STRING AnsiString;
+ PKPROCESS KProcess;
+
+ /*
+ * Register the process object type
+ */
+
+ PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
+
+ PsProcessType->TotalObjects = 0;
+ PsProcessType->TotalHandles = 0;
+ PsProcessType->MaxObjects = ULONG_MAX;
+ PsProcessType->MaxHandles = ULONG_MAX;
+ PsProcessType->PagedPoolCharge = 0;
+ PsProcessType->NonpagedPoolCharge = sizeof(EPROCESS);
+ PsProcessType->Dump = NULL;
+ PsProcessType->Open = NULL;
+ PsProcessType->Close = NULL;
+ PsProcessType->Delete = NULL;
+ PsProcessType->Parse = NULL;
+ PsProcessType->Security = NULL;
+ PsProcessType->QueryName = NULL;
+ PsProcessType->OkayToClose = NULL;
+
+ RtlInitAnsiString(&AnsiString,"Process");
+ RtlAnsiStringToUnicodeString(&PsProcessType->TypeName,&AnsiString,TRUE);
+
+ /*
+ * Initialize the system process
+ */
+ SystemProcess = ObGenericCreateObject(NULL,PROCESS_ALL_ACCESS,NULL,
+ PsProcessType);
+ KProcess = &SystemProcess->Pcb;
+
+ InitializeListHead(&(KProcess->MemoryAreaList));
+ ObInitializeHandleTable(NULL,FALSE,KProcess);
+ KProcess->PageTableDirectory = get_page_directory();
+
+ SystemProcessHandle = ObInsertHandle(KProcess,SystemProcess,
+ PROCESS_ALL_ACCESS,FALSE);
+}
+
+PKPROCESS KeGetCurrentProcess(VOID)
+/*
+ * FUNCTION: Returns a pointer to the current process
+ */
+{
+ return(&(PsGetCurrentProcess()->Pcb));
+}
+
+struct _EPROCESS* PsGetCurrentProcess(VOID)
+/*
+ * FUNCTION: Returns a pointer to the current process
+ */
+{
+ if (PsGetCurrentThread()==NULL
+ || PsGetCurrentThread()->ThreadsProcess==NULL)
+ {
+ return(SystemProcess);
+ }
+ else
+ {
+ return(PsGetCurrentThread()->ThreadsProcess);
+ }
+}
+
+NTSTATUS STDCALL NtCreateProcess(
+ OUT PHANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
+ IN HANDLE ParentProcessHandle,
+ IN BOOLEAN InheritObjectTable,
+ IN HANDLE SectionHandle OPTIONAL,
+ IN HANDLE DebugPort OPTIONAL,
+ IN HANDLE ExceptionPort OPTIONAL)
+{
+ return(ZwCreateProcess(ProcessHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ ParentProcessHandle,
+ InheritObjectTable,
+ SectionHandle,
+ DebugPort,
+ ExceptionPort));
+}
+
+NTSTATUS STDCALL ZwCreateProcess(
+ OUT PHANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
+ IN HANDLE ParentProcessHandle,
+ IN BOOLEAN InheritObjectTable,
+ IN HANDLE SectionHandle OPTIONAL,
+ IN HANDLE DebugPort OPTIONAL,
+ IN HANDLE ExceptionPort OPTIONAL)
+/*
+ * FUNCTION: Creates a process.
+ * ARGUMENTS:
+ * ProcessHandle (OUT) = Caller supplied storage for the resulting
+ * handle
+ * DesiredAccess = Specifies the allowed or desired access to the
+ * process can be a combination of
+ * STANDARD_RIGHTS_REQUIRED| ..
+ * ObjectAttribute = Initialized attributes for the object, contains
+ * the rootdirectory and the filename
+ * ParentProcess = Handle to the parent process.
+ * InheritObjectTable = Specifies to inherit the objects of the parent
+ * process if true.
+ * SectionHandle = Handle to a section object to back the image file
+ * DebugPort = Handle to a DebugPort if NULL the system default debug
+ * port will be used.
+ * ExceptionPort = Handle to a exception port.
+ * REMARKS:
+ * This function maps to the win32 CreateProcess.
+ * RETURNS: Status
+ */
+{
+ PEPROCESS Process;
+ PEPROCESS ParentProcess;
+ PULONG PageDirectory;
+ PULONG CurrentPageDirectory;
+ ULONG i;
+ PKPROCESS KProcess;
+ ULONG Base;
+ ULONG Length;
+ LARGE_INTEGER Offset;
+ NTSTATUS Status;
+
+ DPRINT("ZwCreateProcess(ObjectAttributes %x)\n",ObjectAttributes);
+
+ Status = ObReferenceObjectByHandle(ParentProcessHandle,
+ PROCESS_CREATE_PROCESS,
+ PsProcessType,
+ UserMode,
+ &ParentProcessHandle,
+ NULL);
+
+ if (Status != STATUS_SUCCESS)
+ {
+ DPRINT("ZwCreateProcess() = %x\n",Status);
+ return(Status);
+ }
+
+ Process = ObGenericCreateObject(ProcessHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ PsProcessType);
+ KeInitializeDispatcherHeader(&Process->Pcb.DispatcherHeader,
+ 0,
+ sizeof(EPROCESS),
+ FALSE);
+ KProcess = &(Process->Pcb);
+
+ InitializeListHead(&(KProcess->MemoryAreaList));
+ ObInitializeHandleTable(KProcess,InheritObjectTable,KProcess);
+
+ PageDirectory = physical_to_linear((ULONG)get_free_page());
+ KProcess->PageTableDirectory = PageDirectory;
+
+ CurrentPageDirectory = get_page_directory();
+
+ memset(PageDirectory,0,PAGESIZE);
+ for (i=768;i<1024;i++)
+ {
+ PageDirectory[i]=CurrentPageDirectory[i];
+ }
+
+ /*
+ * FIXME: I don't what I'm supposed to know with a section handle
+ */
+ if (SectionHandle != NULL)
+ {
+ DbgPrint("ZwCreateProcess() non-NULL SectionHandle\n");
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ Process->Pcb.ProcessState = PROCESS_STATE_ACTIVE;
+
+ return(STATUS_SUCCESS);
+}
+
+
+NTSTATUS STDCALL NtOpenProcess (OUT PHANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN PCLIENT_ID ClientId)
+{
+ return(ZwOpenProcess(ProcessHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ ClientId));
+}
+
+NTSTATUS STDCALL ZwOpenProcess (OUT PHANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN PCLIENT_ID ClientId)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtQueryInformationProcess(IN HANDLE ProcessHandle,
+ IN CINT ProcessInformationClass,
+ OUT PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength,
+ OUT PULONG ReturnLength)
+{
+ return(ZwQueryInformationProcess(ProcessHandle,
+ ProcessInformationClass,
+ ProcessInformation,
+ ProcessInformationLength,
+ ReturnLength));
+}
+
+NTSTATUS STDCALL ZwQueryInformationProcess(IN HANDLE ProcessHandle,
+ IN CINT ProcessInformationClass,
+ OUT PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength,
+ OUT PULONG ReturnLength)
+{
+ PEPROCESS Process;
+ NTSTATUS Status;
+
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_QUERY_INFORMATION,
+ PsProcessType,
+ UserMode,
+ &ProcessHandle,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ switch (ProcessInformationClass)
+ {
+ case ProcessBasicInformation:
+ case ProcessQuotaLimits:
+ case ProcessIoCounters:
+ case ProcessVmCounters:
+ case ProcessTimes:
+ case ProcessBasePriority:
+ case ProcessRaisePriority:
+ case ProcessDebugPort:
+ case ProcessExceptionPort:
+ case ProcessAccessToken:
+ case ProcessLdtInformation:
+ case ProcessLdtSize:
+ case ProcessDefaultHardErrorMode:
+ case ProcessIoPortHandlers:
+ case ProcessWorkingSetWatch:
+ case ProcessUserModeIOPL:
+ case ProcessEnableAlignmentFaultFixup:
+ case ProcessPriorityClass:
+ case ProcessWx86Information:
+ case ProcessHandleCount:
+ case ProcessAffinityMask:
+ default:
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+ return(Status);
+}
+
+NTSTATUS STDCALL NtSetInformationProcess(IN HANDLE ProcessHandle,
+ IN CINT ProcessInformationClass,
+ IN PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength)
+{
+ return(ZwSetInformationProcess(ProcessHandle,
+ ProcessInformationClass,
+ ProcessInformation,
+ ProcessInformationLength));
+}
+
+NTSTATUS STDCALL ZwSetInformationProcess(IN HANDLE ProcessHandle,
+ IN CINT ProcessInformationClass,
+ IN PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength)
+{
+ UNIMPLEMENTED;
+}
+
return NULL;
}
+#if 0
wchar_t towupper(wchar_t w)
{
if (w < L'A')
{
- return(w+'A');
+ return(w + 'A');
}
else
{
return(w);
}
}
+#endif
int wcsicmp(const wchar_t* cs, const wchar_t* ct)
{
#endif
-unsigned long wstrlen(PWSTR s)
+size_t wstrlen(const wchar_t *s)
{
return wcslen(s);
}
}
-void TstDriverLoad(void)
-{
- NTSTATUS Status;
- ANSI_STRING AnsiDriverName;
- UNICODE_STRING DriverName;
-
- RtlInitAnsiString(&AnsiDriverName,"\\??\\C:\\reactos\\system\\keyboard.o");
- RtlAnsiStringToUnicodeString(&DriverName, &AnsiDriverName, TRUE);
- Status = LdrLoadDriver(&DriverName);
- RtlFreeUnicodeString(&DriverName);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("driver load failed, status;%d(%x)\n", Status, Status);
- DbgPrintErrorMessage(Status);
- }
- RtlInitAnsiString(&AnsiDriverName,"\\??\\C:\\reactos\\system\\beep.sys");
- RtlAnsiStringToUnicodeString(&DriverName, &AnsiDriverName, TRUE);
- Status = LdrLoadDriver(&DriverName);
- RtlFreeUnicodeString(&DriverName);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("driver load failed, status;%d(%x)\n", Status, Status);
- DbgPrintErrorMessage(Status);
- }
-}
-
void TstBegin()
{
- TstDriverLoad();
ExExecuteShell();
// TstFileRead();
// TstGeneralWrite();