mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 00:54:40 +00:00
Initial revision
svn path=/trunk/; revision=50
This commit is contained in:
parent
5c0fb0f108
commit
645218d5c8
160 changed files with 18523 additions and 0 deletions
21
reactos/DIRS
Normal file
21
reactos/DIRS
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
DIRECTORIES
|
||||||
|
|
||||||
|
system : compiled versions of the various system components and
|
||||||
|
libraries
|
||||||
|
ntoskrnl : microkernel source
|
||||||
|
ntoskrnl/hal : hardware abstraction layer source
|
||||||
|
ntoskrnl/mm : memory managment subsystem source
|
||||||
|
ntoskrnl/io : IO manager subsystem source
|
||||||
|
include : win32 headers
|
||||||
|
include/internal : kernel private header files
|
||||||
|
include/ntdll : system library private header files
|
||||||
|
include/kernel32 : system library private header files
|
||||||
|
include/user32 : user interface private header files
|
||||||
|
include/gdi32 : graphics interface private header files
|
||||||
|
include/ddk : header files for modules
|
||||||
|
lib/ntdll : NT dll source
|
||||||
|
lib/kernel32 : kernel32 source
|
||||||
|
doc : documentation
|
||||||
|
loaders/dos : DOS based loader
|
||||||
|
loaders/boot : boot loader
|
||||||
|
services : various services (device drivers, filesystems etc)
|
10
reactos/NEWS
Normal file
10
reactos/NEWS
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
0.0.12: Added support for multiple processes (not really tested)
|
||||||
|
System calls
|
||||||
|
kernel32 now compiles (only as a static library)
|
||||||
|
Fixed invalid tss bug (hopefully)
|
||||||
|
Added section support
|
||||||
|
Added some of the ZwxxxVirtual calls
|
||||||
|
Added prototype caching functions (only the Minix fsd actually
|
||||||
|
uses them)
|
||||||
|
Added handle access and type checking
|
||||||
|
Prototype APC implementation (no support for user APCs)
|
62
reactos/README
Normal file
62
reactos/README
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
Last updated 30/09/98
|
||||||
|
|
||||||
|
-- Compiling
|
||||||
|
|
||||||
|
Type 'make' to build the kernel on linux using a djgpp cross compiler, or
|
||||||
|
'make -fmakefile.dos' to build the kernel from dos using djgpp. No other
|
||||||
|
configuration are supported at the moment, sorry.
|
||||||
|
|
||||||
|
-- Running
|
||||||
|
|
||||||
|
To run the kernel start from a clean dos system (no emm386 or windows) and
|
||||||
|
run 'boot.bat'. The kernel should boot, print diagnostic messages and begin
|
||||||
|
executing a simple user-mode shell. By default the kernel boots with a
|
||||||
|
minimum set of drivers but additional ones can be specified as the arguments
|
||||||
|
to 'boot.bat'.
|
||||||
|
|
||||||
|
-- Problems
|
||||||
|
|
||||||
|
This is strictly alpha quality software so expect plenty of those. If you
|
||||||
|
are submitting a bug report, please see the section below. If you have a fix
|
||||||
|
for the problem, even better, please send all patches, fixes, enhancements etc
|
||||||
|
to me (David Welch), our coordinator Dennis Winkley or the kernel mailing
|
||||||
|
list. (See contact addresses below)
|
||||||
|
|
||||||
|
-- Bug Reports
|
||||||
|
|
||||||
|
Thank you for taking the time to do this, we can only fix the bugs we know
|
||||||
|
about, however please include as much information as possible. Say what you
|
||||||
|
were trying to do at the time, what messages (if any) were displayed. If the
|
||||||
|
kernel crashed, it should print a message like this
|
||||||
|
|
||||||
|
Exception s(r)
|
||||||
|
CS:EIP p(q)
|
||||||
|
DS xxxxx ES xxxx FS xxxx
|
||||||
|
...
|
||||||
|
Frames: xxxxx xxxxx xxxxx
|
||||||
|
|
||||||
|
Please include the exception type and error code (s and r). The eip
|
||||||
|
address (q) is specific to your kernel, to be of use in fixing the problem
|
||||||
|
it needs to be translated to a function name. Do this by running
|
||||||
|
|
||||||
|
nm --numeric-sort kimage > kernel.sym
|
||||||
|
|
||||||
|
kernel.sym should include a list of functions and their address, look for the
|
||||||
|
last function with an address less than the eip value. The functions should
|
||||||
|
sorted in ascending order by address.
|
||||||
|
|
||||||
|
If you suspect the problem is hardware related also include details of what
|
||||||
|
hardware devices you have installed.
|
||||||
|
|
||||||
|
-- Contact addresses
|
||||||
|
|
||||||
|
Overall coordinator, Jason Filby (jasonfilby@yahoo.com)
|
||||||
|
Kernel coordinator, Dennis Winkley (dwinkley@mail.whitworth.edu)
|
||||||
|
Me, David Welch (welch@mcmail.com)
|
||||||
|
|
||||||
|
Specific components will probably have contact details for the authors in
|
||||||
|
the source file, a partial list of those working on the kernel can be found
|
||||||
|
on the kernel website.
|
||||||
|
|
||||||
|
-- Additional documentation
|
||||||
|
|
11
reactos/TODO
Normal file
11
reactos/TODO
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Hardware resource management
|
||||||
|
Deleting namespace objects
|
||||||
|
Directory functions
|
||||||
|
File sharing
|
||||||
|
Event pairs
|
||||||
|
Io completion ports
|
||||||
|
Cancel io support
|
||||||
|
DMA support
|
||||||
|
Registry support
|
||||||
|
Cache read ahead
|
||||||
|
Caching file mapping
|
11
reactos/apps/common/crt0.c
Normal file
11
reactos/apps/common/crt0.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
extern void main(void);
|
||||||
|
|
||||||
|
void start(void)
|
||||||
|
{
|
||||||
|
main();
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __main(void)
|
||||||
|
{
|
||||||
|
}
|
7
reactos/apps/tests/hello/makefile
Normal file
7
reactos/apps/tests/hello/makefile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
all: test.bin
|
||||||
|
|
||||||
|
test.bin: test.asm
|
||||||
|
$(LD) -Ttext 0x10000 test.o ../../lib/ntdll/ntdll.a -o test.exe
|
||||||
|
$(OBJCOPY) -O binary test.exe test.bin
|
||||||
|
|
||||||
|
include ../../rules.mak
|
11
reactos/apps/tests/hello/test.asm
Normal file
11
reactos/apps/tests/hello/test.asm
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
BITS 32
|
||||||
|
|
||||||
|
EXTERN _NtDisplayString
|
||||||
|
|
||||||
|
_main:
|
||||||
|
push dword _string
|
||||||
|
call _NtDisplayString
|
||||||
|
l1:
|
||||||
|
jmp l1
|
||||||
|
|
||||||
|
_string db 'Hello world from user mode!',0xa,0
|
158
reactos/apps/utils/cmd/cmd.c
Normal file
158
reactos/apps/utils/cmd/cmd.c
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
HANDLE stdin;
|
||||||
|
HANDLE stdout;
|
||||||
|
|
||||||
|
|
||||||
|
void Console_puts(char* str)
|
||||||
|
{
|
||||||
|
ULONG nchar;
|
||||||
|
|
||||||
|
WriteConsole(stdout,
|
||||||
|
str,
|
||||||
|
strlen(str),
|
||||||
|
&nchar,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console_printf(char* fmt, ...)
|
||||||
|
{
|
||||||
|
char buffer[255];
|
||||||
|
va_list vargs;
|
||||||
|
|
||||||
|
va_start(vargs,fmt);
|
||||||
|
vsprintf(buffer,fmt,vargs);
|
||||||
|
Console_puts(buffer);
|
||||||
|
va_end(vargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console_getline(PCH Prompt, PCH Output, DWORD OutputLength)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
DWORD nbytes;
|
||||||
|
|
||||||
|
Console_puts(Prompt);
|
||||||
|
|
||||||
|
ReadConsole(stdin,
|
||||||
|
Output,
|
||||||
|
OutputLength,
|
||||||
|
&nbytes,
|
||||||
|
NULL);
|
||||||
|
Output[nbytes-2]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void func_cd(char* s)
|
||||||
|
{
|
||||||
|
Console_printf("Changing directory to %s\n",s);
|
||||||
|
if (!SetCurrentDirectory(s))
|
||||||
|
{
|
||||||
|
Console_puts("Failed to change to directory\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void func_dir(char* s)
|
||||||
|
{
|
||||||
|
HANDLE shandle;
|
||||||
|
WIN32_FIND_DATA FindData;
|
||||||
|
|
||||||
|
shandle = FindFirstFile("*.*",&FindData);
|
||||||
|
|
||||||
|
if (shandle==INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Console_printf("Scanning %s\n",FindData.cFileName);
|
||||||
|
} while(FindNextFile(shandle,&FindData));
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_builtin(char* name, char* args)
|
||||||
|
{
|
||||||
|
if (strcmp(name,"dir")==0)
|
||||||
|
{
|
||||||
|
func_dir(args);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
if (strcmp(name,"cd")==0)
|
||||||
|
{
|
||||||
|
func_cd(args);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int process_command(char* str)
|
||||||
|
{
|
||||||
|
char* name;
|
||||||
|
char* args;
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
STARTUPINFO si;
|
||||||
|
char process_arg[255];
|
||||||
|
|
||||||
|
if (strcmp(str,"exit")==0)
|
||||||
|
{
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
name = strtok(str," \t");
|
||||||
|
args = strtok(NULL,"");
|
||||||
|
|
||||||
|
if (is_builtin(name,args))
|
||||||
|
{
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
memset(&si,0,sizeof(STARTUPINFO));
|
||||||
|
si.cb=sizeof(STARTUPINFO);
|
||||||
|
si.lpTitle=strdup(name);
|
||||||
|
|
||||||
|
strcpy(process_arg,name);
|
||||||
|
strcat(process_arg," ");
|
||||||
|
if(args!=NULL)
|
||||||
|
{
|
||||||
|
strcat(process_arg,args);
|
||||||
|
}
|
||||||
|
Console_printf("name '%s' process_arg '%s'\n",name,process_arg);
|
||||||
|
if (!CreateProcess(NULL,process_arg,NULL,NULL,FALSE,
|
||||||
|
CREATE_NEW_CONSOLE,
|
||||||
|
NULL,NULL,&si,&pi))
|
||||||
|
{
|
||||||
|
Console_printf("Failed to execute process\n");
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void build_prompt(char* prompt)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = GetCurrentDirectory(255,prompt);
|
||||||
|
strcat(prompt,">");
|
||||||
|
}
|
||||||
|
|
||||||
|
void command_loop()
|
||||||
|
{
|
||||||
|
char line[255];
|
||||||
|
char prompt[255];
|
||||||
|
int do_exit = 0;
|
||||||
|
|
||||||
|
while (!do_exit)
|
||||||
|
{
|
||||||
|
build_prompt(prompt);
|
||||||
|
Console_getline(prompt,line,255);
|
||||||
|
Console_printf("Processing command '%s'\n",line);
|
||||||
|
do_exit = process_command(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int STDCALL WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
|
||||||
|
{
|
||||||
|
AllocConsole();
|
||||||
|
stdin = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
stdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
command_loop();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
12
reactos/apps/utils/cmd/makefile
Normal file
12
reactos/apps/utils/cmd/makefile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
all: cmd.bin
|
||||||
|
|
||||||
|
OBJECTS = ../common/crt0.o cmd.o
|
||||||
|
|
||||||
|
LIBS = ../../lib/mingw32/mingw32.a ../../lib/crtdll/crtdll.a \
|
||||||
|
../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a
|
||||||
|
|
||||||
|
cmd.bin: $(OBJECTS)
|
||||||
|
$(LD) -Ttext 0x10000 $(OBJECTS) $(LIBS) -o cmd.exe
|
||||||
|
$(OBJCOPY) -O binary cmd.exe cmd.bin
|
||||||
|
|
||||||
|
include ../../rules.mak
|
9
reactos/apps/utils/shell/makefile
Normal file
9
reactos/apps/utils/shell/makefile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
all: shell.bin
|
||||||
|
|
||||||
|
OBJECTS = ../common/crt0.o shell.o
|
||||||
|
|
||||||
|
shell.bin: $(OBJECTS)
|
||||||
|
$(LD) -Ttext 0x10000 $(OBJECTS) ../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a -o shell.exe
|
||||||
|
$(OBJCOPY) -O binary shell.exe shell.bin
|
||||||
|
|
||||||
|
include ../../rules.mak
|
46
reactos/apps/utils/shell/shell.c
Normal file
46
reactos/apps/utils/shell/shell.c
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
void debug_printf(char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char buffer[255];
|
||||||
|
|
||||||
|
va_start(args,fmt);
|
||||||
|
vsprintf(buffer,fmt,args);
|
||||||
|
OutputDebugString(buffer);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
KEY_EVENT_RECORD KeyEvent[2];
|
||||||
|
HANDLE FileHandle;
|
||||||
|
DWORD Result;
|
||||||
|
HANDLE DefaultHeap;
|
||||||
|
PVOID Buffer;
|
||||||
|
|
||||||
|
NtDisplayString("Simple Shell Starting...\n");
|
||||||
|
|
||||||
|
// DefaultHeap = HeapCreate(0,1024*1024,1024*1024);
|
||||||
|
// Buffer = HeapAlloc(DefaultHeap,0,1024);
|
||||||
|
|
||||||
|
FileHandle = CreateFile("\\Device\\Keyboard",
|
||||||
|
FILE_GENERIC_READ,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
debug_printf("C:\\");
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
ReadFile(FileHandle,
|
||||||
|
&KeyEvent,
|
||||||
|
sizeof(KeyEvent),
|
||||||
|
&Result,
|
||||||
|
NULL);
|
||||||
|
debug_printf("%c",KeyEvent[0].AsciiChar);
|
||||||
|
}
|
||||||
|
}
|
796
reactos/apps/utils/shell/shell.sym
Normal file
796
reactos/apps/utils/shell/shell.sym
Normal file
|
@ -0,0 +1,796 @@
|
||||||
|
00000000 a .absolut
|
||||||
|
00010000 t .text
|
||||||
|
00010000 t ___gnu_compiled_c
|
||||||
|
00010000 T _start
|
||||||
|
00010000 t gcc2_compiled.
|
||||||
|
00010008 t L4
|
||||||
|
0001000a T ___main
|
||||||
|
00010010 t .text
|
||||||
|
00010010 t LC0
|
||||||
|
00010010 t ___gnu_compiled_c
|
||||||
|
00010010 t gcc2_compiled.
|
||||||
|
0001002a t LC1
|
||||||
|
0001003c T _main
|
||||||
|
00010070 t L18
|
||||||
|
00010074 t .text
|
||||||
|
00010074 t LC0
|
||||||
|
00010074 t ___gnu_compiled_c
|
||||||
|
00010074 t gcc2_compiled.
|
||||||
|
00010098 t ___HeapCommit
|
||||||
|
000100c5 t L124
|
||||||
|
000100e2 t L125
|
||||||
|
000100e4 t L126
|
||||||
|
000100ec t LC1
|
||||||
|
00010112 t ___HeapDecommit
|
||||||
|
00010145 t L128
|
||||||
|
0001015e t ___HeapAlloc
|
||||||
|
0001019a t L132
|
||||||
|
000101cc t L131
|
||||||
|
00010209 t L136
|
||||||
|
0001024c t L135
|
||||||
|
00010282 t L169
|
||||||
|
0001028c t L139
|
||||||
|
000102c8 t L142
|
||||||
|
000102ce t L168
|
||||||
|
000102d6 t ___HeapFreeRest
|
||||||
|
000102f4 t L171
|
||||||
|
00010341 t L172
|
||||||
|
0001035f t L170
|
||||||
|
00010367 t LC2
|
||||||
|
00010386 t LC3
|
||||||
|
000103a7 t LC4
|
||||||
|
000103c2 t LC5
|
||||||
|
000103e1 t LC6
|
||||||
|
00010408 t ___HeapReAlloc
|
||||||
|
00010430 t L175
|
||||||
|
00010470 t L176
|
||||||
|
000104f2 t L178
|
||||||
|
00010510 t L244
|
||||||
|
00010518 t L181
|
||||||
|
000105ca t L185
|
||||||
|
0001063e t L184
|
||||||
|
0001068c t L215
|
||||||
|
000106cd t L216
|
||||||
|
000106e0 t L214
|
||||||
|
000106ea t L177
|
||||||
|
000106ec t L243
|
||||||
|
000106f4 t ___HeapFree
|
||||||
|
00010712 t L246
|
||||||
|
00010775 t L248
|
||||||
|
00010785 t L247
|
||||||
|
000107d6 t L249
|
||||||
|
00010802 t L251
|
||||||
|
00010807 t L252
|
||||||
|
00010810 t ___HeapAllocSub
|
||||||
|
00010840 t L254
|
||||||
|
00010882 t L258
|
||||||
|
000108b1 t L256
|
||||||
|
000108bd t L260
|
||||||
|
000108c6 t ___HeapAllocFragment
|
||||||
|
000108e4 t L264
|
||||||
|
000108f0 t L263
|
||||||
|
0001090c t L267
|
||||||
|
00010940 t L268
|
||||||
|
00010984 t L269
|
||||||
|
0001098a t L295
|
||||||
|
00010992 t ___HeapReAllocFragment
|
||||||
|
000109bc t L297
|
||||||
|
000109d8 t L298
|
||||||
|
00010a06 t L301
|
||||||
|
00010a17 t L302
|
||||||
|
00010a28 t L303
|
||||||
|
00010a5f t L304
|
||||||
|
00010a72 t L299
|
||||||
|
00010a74 t L330
|
||||||
|
00010a7c t ___HeapFreeFragment
|
||||||
|
00010aab t L343
|
||||||
|
00010ab8 t L333
|
||||||
|
00010ad3 t L335
|
||||||
|
00010ae0 t L336
|
||||||
|
00010aed t L337
|
||||||
|
00010b02 t L334
|
||||||
|
00010b26 t L340
|
||||||
|
00010b37 t L339
|
||||||
|
00010b3c t L342
|
||||||
|
00010b44 t ___HeapPrepare
|
||||||
|
00010ba2 t L345
|
||||||
|
00010bb2 t L346
|
||||||
|
00010be0 T ___HeapInit
|
||||||
|
00010c23 t LC7
|
||||||
|
00010c46 T _HeapCreate
|
||||||
|
00010c99 t LC8
|
||||||
|
00010cb0 T _HeapDestroy
|
||||||
|
00010cea t L350
|
||||||
|
00010cf1 t L351
|
||||||
|
00010cf8 t LC9
|
||||||
|
00010d1a t LC10
|
||||||
|
00010d34 T _HeapAlloc
|
||||||
|
00010d65 t L353
|
||||||
|
00010d82 t L354
|
||||||
|
00010d8f t L355
|
||||||
|
00010da1 t L356
|
||||||
|
00010db8 t LC11
|
||||||
|
00010de4 T _HeapReAlloc
|
||||||
|
00010e19 t L358
|
||||||
|
00010e36 t L359
|
||||||
|
00010e47 t L364
|
||||||
|
00010e4e t L361
|
||||||
|
00010e5a t L360
|
||||||
|
00010e6d t L363
|
||||||
|
00010e79 t LC12
|
||||||
|
00010e9a T _HeapFree
|
||||||
|
00010ecb t L366
|
||||||
|
00010ee4 t L367
|
||||||
|
00010ef2 t L372
|
||||||
|
00010efa t L369
|
||||||
|
00010f06 t L368
|
||||||
|
00010f18 t L371
|
||||||
|
00010f24 t LC13
|
||||||
|
00010f36 T _GetProcessHeap
|
||||||
|
00010f4a t LC14
|
||||||
|
00010f68 T _GetProcessHeaps
|
||||||
|
00010f8c t L379
|
||||||
|
00010fa4 t L382
|
||||||
|
00010fab t L384
|
||||||
|
00010faf t L381
|
||||||
|
00010fb8 t LC15
|
||||||
|
00010fcc T _HeapLock
|
||||||
|
00010ff3 t LC16
|
||||||
|
00011008 T _HeapUnlock
|
||||||
|
00011030 T _HeapCompact
|
||||||
|
0001104e t L388
|
||||||
|
00011056 t L389
|
||||||
|
0001106a t L392
|
||||||
|
00011092 t L394
|
||||||
|
0001109e t LC17
|
||||||
|
000110c0 T _HeapSize
|
||||||
|
000110f4 t L396
|
||||||
|
00011107 t L397
|
||||||
|
00011122 t L399
|
||||||
|
0001112e t L401
|
||||||
|
0001113a t L398
|
||||||
|
0001114d t L403
|
||||||
|
0001114f t L404
|
||||||
|
00011159 t LC18
|
||||||
|
000111b2 t LC19
|
||||||
|
00011200 t LC20
|
||||||
|
0001124f t LC21
|
||||||
|
000112a0 t LC22
|
||||||
|
000112f5 t LC23
|
||||||
|
00011343 t LC24
|
||||||
|
0001138b t LC25
|
||||||
|
000113b1 t LC26
|
||||||
|
000113dc t LC27
|
||||||
|
00011420 T _HeapValidate
|
||||||
|
00011444 t L406
|
||||||
|
0001145e t L408
|
||||||
|
0001149a t L411
|
||||||
|
000114ce t L413
|
||||||
|
000114e8 t L417
|
||||||
|
00011504 t L418
|
||||||
|
0001151c t L419
|
||||||
|
0001152e t L420
|
||||||
|
00011546 t L421
|
||||||
|
00011552 t L415
|
||||||
|
00011568 t L423
|
||||||
|
00011588 t L412
|
||||||
|
000115a9 t L434
|
||||||
|
000115b2 t L426
|
||||||
|
000115be t L425
|
||||||
|
000115d3 t L433
|
||||||
|
000115dc t L428
|
||||||
|
000115e5 t L435
|
||||||
|
000115ed t L424
|
||||||
|
0001160d t L407
|
||||||
|
00011625 t L431
|
||||||
|
0001162a t L432
|
||||||
|
00011634 t .text
|
||||||
|
00011634 T _OutputDebugStringA
|
||||||
|
00011634 t ___gnu_compiled_c
|
||||||
|
00011634 t gcc2_compiled.
|
||||||
|
00011644 T _dprintf
|
||||||
|
00011670 T _aprintf
|
||||||
|
0001169c t .text
|
||||||
|
0001169c T _VirtualAllocEx
|
||||||
|
0001169c t ___gnu_compiled_c
|
||||||
|
0001169c t gcc2_compiled.
|
||||||
|
000116c2 t L16
|
||||||
|
000116c8 T _VirtualAlloc
|
||||||
|
000116e6 T _VirtualFreeEx
|
||||||
|
00011708 t L20
|
||||||
|
0001170e T _VirtualFree
|
||||||
|
0001172a T _VirtualProtect
|
||||||
|
00011748 T _VirtualProtectEx
|
||||||
|
0001176c t L25
|
||||||
|
00011774 t .text
|
||||||
|
00011774 T _RtlNtStatusToDosError
|
||||||
|
00011774 t ___gnu_compiled_c
|
||||||
|
00011774 t gcc2_compiled.
|
||||||
|
0001177c T _SetLastError
|
||||||
|
0001178c T _GetLastError
|
||||||
|
00011796 T ___ErrorReturnFalse
|
||||||
|
0001179e T ___ErrorReturnNull
|
||||||
|
000117a8 t .text
|
||||||
|
000117a8 T _CopyMemory
|
||||||
|
000117a8 t ___gnu_compiled_c
|
||||||
|
000117a8 t gcc2_compiled.
|
||||||
|
000117bc t L5
|
||||||
|
000117c7 t L3
|
||||||
|
000117d0 t .text
|
||||||
|
000117d0 T _DeleteCriticalSection
|
||||||
|
000117d0 t ___gnu_compiled_c
|
||||||
|
000117d0 t gcc2_compiled.
|
||||||
|
000117e2 T _EnterCriticalSection
|
||||||
|
000117ea T _InitializeCriticalSection
|
||||||
|
00011818 T _LeaveCriticalSection
|
||||||
|
00011820 T _TryEntryCriticalSection
|
||||||
|
00011828 t .text
|
||||||
|
00011828 t ___gnu_compiled_c
|
||||||
|
00011828 T _simple_strtoul
|
||||||
|
00011828 t gcc2_compiled.
|
||||||
|
00011870 t L163
|
||||||
|
00011872 t L162
|
||||||
|
00011884 t L165
|
||||||
|
00011886 t L164
|
||||||
|
0001188a t L188
|
||||||
|
00011890 t L166
|
||||||
|
000118a8 t L174
|
||||||
|
000118aa t L173
|
||||||
|
000118bc t L176
|
||||||
|
000118be t L175
|
||||||
|
000118c2 t L189
|
||||||
|
000118cf t L180
|
||||||
|
000118dc t L177
|
||||||
|
000118e9 t L184
|
||||||
|
000118f8 t L186
|
||||||
|
000118fa t L185
|
||||||
|
00011900 t L181
|
||||||
|
00011903 t L190
|
||||||
|
00011906 t L178
|
||||||
|
0001191c t L167
|
||||||
|
00011927 t L187
|
||||||
|
00011932 t _skip_atoi
|
||||||
|
0001193e t L194
|
||||||
|
0001194c t L196
|
||||||
|
0001195d t LC0
|
||||||
|
00011982 t LC1
|
||||||
|
000119a8 t _number
|
||||||
|
000119cc t L198
|
||||||
|
000119d8 t L199
|
||||||
|
000119ea t L200
|
||||||
|
000119f9 t L201
|
||||||
|
00011a14 t L204
|
||||||
|
00011a22 t L206
|
||||||
|
00011a2d t L252
|
||||||
|
00011a2e t L203
|
||||||
|
00011a40 t L210
|
||||||
|
00011a47 t L209
|
||||||
|
00011a5a t L251
|
||||||
|
00011a5e t L217
|
||||||
|
00011a79 t L214
|
||||||
|
00011a81 t L219
|
||||||
|
00011a8c t L223
|
||||||
|
00011a90 t L253
|
||||||
|
00011a97 t L220
|
||||||
|
00011aa3 t L225
|
||||||
|
00011ab6 t L227
|
||||||
|
00011ac8 t L254
|
||||||
|
00011ac9 t L226
|
||||||
|
00011ad8 t L233
|
||||||
|
00011aea t L237
|
||||||
|
00011aee t L255
|
||||||
|
00011afa t L241
|
||||||
|
00011b01 t L256
|
||||||
|
00011b0a t L245
|
||||||
|
00011b0e t L257
|
||||||
|
00011b17 t L247
|
||||||
|
00011b1f t LC2
|
||||||
|
00011b26 T _vsprintf
|
||||||
|
00011b3e t L262
|
||||||
|
00011b50 t L264
|
||||||
|
00011b72 t L271
|
||||||
|
00011bb6 t L266
|
||||||
|
00011bbc t L267
|
||||||
|
00011bc2 t L268
|
||||||
|
00011bc8 t L269
|
||||||
|
00011bce t L270
|
||||||
|
00011bd8 t L265
|
||||||
|
00011bfc t L273
|
||||||
|
00011c1a t L274
|
||||||
|
00011c4c t L278
|
||||||
|
00011c64 t L279
|
||||||
|
00011c6a t L277
|
||||||
|
00011c85 t L283
|
||||||
|
00011c95 t L282
|
||||||
|
00011cb8 t L339
|
||||||
|
00011d3c t L285
|
||||||
|
00011d46 t L289
|
||||||
|
00011d4a t L351
|
||||||
|
00011d4f t L286
|
||||||
|
00011d68 t L293
|
||||||
|
00011d76 t L295
|
||||||
|
00011d96 t L299
|
||||||
|
00011da6 t L296
|
||||||
|
00011db0 t L304
|
||||||
|
00011dc4 t L306
|
||||||
|
00011dd7 t L307
|
||||||
|
00011df6 t L312
|
||||||
|
00011dfa t L352
|
||||||
|
00011e01 t L309
|
||||||
|
00011e0e t L317
|
||||||
|
00011e1c t L315
|
||||||
|
00011e28 t L321
|
||||||
|
00011e38 t L323
|
||||||
|
00011e46 t L324
|
||||||
|
00011e5c t L325
|
||||||
|
00011e72 t L328
|
||||||
|
00011e7a t L329
|
||||||
|
00011e82 t L330
|
||||||
|
00011e86 t L331
|
||||||
|
00011e8e t L333
|
||||||
|
00011e94 t L335
|
||||||
|
00011ea0 t L336
|
||||||
|
00011ea9 t L350
|
||||||
|
00011eae t L337
|
||||||
|
00011eb4 t L284
|
||||||
|
00011ed6 t L343
|
||||||
|
00011ee6 t L342
|
||||||
|
00011efc t L346
|
||||||
|
00011f06 t L354
|
||||||
|
00011f09 t L341
|
||||||
|
00011f12 t L353
|
||||||
|
00011f1d t L261
|
||||||
|
00011f38 t L260
|
||||||
|
00011f48 T _sprintf
|
||||||
|
00011f5c t .text
|
||||||
|
00011f5c T _GetCurrentProcess
|
||||||
|
00011f5c t ___gnu_compiled_c
|
||||||
|
00011f5c t gcc2_compiled.
|
||||||
|
00011f66 T _GetCurrentThread
|
||||||
|
00011f70 t .text
|
||||||
|
00011f70 T _NtAcceptConnectPort
|
||||||
|
00011f70 T _ZwAcceptConnectPort
|
||||||
|
00011f7e T _NtAccessCheck
|
||||||
|
00011f7e T _ZwAccessCheck
|
||||||
|
00011f8c T _NtAccessCheckAndAuditAlarm
|
||||||
|
00011f8c T _ZwAccessCheckAndAuditAlarm
|
||||||
|
00011f9a T _NtAddAtom
|
||||||
|
00011f9a T _ZwAddAtom
|
||||||
|
00011fa8 T _NtAdjustGroupsToken
|
||||||
|
00011fa8 T _ZwAdjustGroupsToken
|
||||||
|
00011fb6 T _NtAdjustPrivilegesToken
|
||||||
|
00011fb6 T _ZwAdjustPrivilegesToken
|
||||||
|
00011fc4 T _NtAlertResumeThread
|
||||||
|
00011fc4 T _ZwAlertResumeThread
|
||||||
|
00011fd2 T _NtAlertThread
|
||||||
|
00011fd2 T _ZwAlertThread
|
||||||
|
00011fe0 T _NtAllocateLocallyUniqueId
|
||||||
|
00011fe0 T _ZwAllocateLocallyUniqueId
|
||||||
|
00011fee T _NtAllocateUuids
|
||||||
|
00011fee T _ZwAllocateUuids
|
||||||
|
00011ffc T _NtAllocateVirtualMemory
|
||||||
|
00011ffc T _ZwAllocateVirtualMemory
|
||||||
|
0001200a T _NtCallbackReturn
|
||||||
|
0001200a T _ZwCallbackReturn
|
||||||
|
00012018 T _NtCancelIoFile
|
||||||
|
00012018 T _ZwCancelIoFile
|
||||||
|
00012026 T _NtCancelTimer
|
||||||
|
00012026 T _ZwCancelTimer
|
||||||
|
00012034 T _NtClearEvent
|
||||||
|
00012034 T _ZwClearEvent
|
||||||
|
00012042 T _NtClose
|
||||||
|
00012042 T _ZwClose
|
||||||
|
00012050 T _NtCloseObjectAuditAlarm
|
||||||
|
00012050 T _ZwCloseObjectAuditAlarm
|
||||||
|
0001205e T _NtCompleteConnectPort
|
||||||
|
0001205e T _ZwCompleteConnectPort
|
||||||
|
0001206c T _NtConnectPort
|
||||||
|
0001206c T _ZwConnectPort
|
||||||
|
0001207a T _NtContinue
|
||||||
|
0001207a T _ZwContinue
|
||||||
|
00012088 T _NtCreateDirectoryObject
|
||||||
|
00012088 T _ZwCreateDirectoryObject
|
||||||
|
00012096 T _NtCreateEvent
|
||||||
|
00012096 T _ZwCreateEvent
|
||||||
|
000120a4 T _NtCreateEventPair
|
||||||
|
000120a4 T _ZwCreateEventPair
|
||||||
|
000120b2 T _NtCreateFile
|
||||||
|
000120b2 T _ZwCreateFile
|
||||||
|
000120c0 T _NtCreateIoCompletion
|
||||||
|
000120c0 T _ZwCreateIoCompletion
|
||||||
|
000120ce T _NtCreateKey
|
||||||
|
000120ce T _ZwCreateKey
|
||||||
|
000120dc T _NtCreateMailslotFile
|
||||||
|
000120dc T _ZwCreateMailslotFile
|
||||||
|
000120ea T _NtCreateMutant
|
||||||
|
000120ea T _ZwCreateMutant
|
||||||
|
000120f8 T _NtCreateNamedPipeFile
|
||||||
|
000120f8 T _ZwCreateNamedPipeFile
|
||||||
|
00012106 T _NtCreatePagingFile
|
||||||
|
00012106 T _ZwCreatePagingFile
|
||||||
|
00012114 T _NtCreatePort
|
||||||
|
00012114 T _ZwCreatePort
|
||||||
|
00012122 T _NtCreateProcess
|
||||||
|
00012122 T _ZwCreateProcess
|
||||||
|
00012130 T _NtCreateProfile
|
||||||
|
00012130 T _ZwCreateProfile
|
||||||
|
0001213e T _NtCreateSection
|
||||||
|
0001213e T _ZwCreateSection
|
||||||
|
0001214c T _NtCreateSemaphore
|
||||||
|
0001214c T _ZwCreateSemaphore
|
||||||
|
0001215a T _NtCreateSymbolicLinkObject
|
||||||
|
0001215a T _ZwCreateSymbolicLinkObject
|
||||||
|
00012168 T _NtCreateThread
|
||||||
|
00012168 T _ZwCreateThread
|
||||||
|
00012176 T _NtCreateTimer
|
||||||
|
00012176 T _ZwCreateTimer
|
||||||
|
00012184 T _NtCreateToken
|
||||||
|
00012184 T _ZwCreateToken
|
||||||
|
00012192 T _NtDelayExecution
|
||||||
|
00012192 T _ZwDelayExecution
|
||||||
|
000121a0 T _NtDeleteAtom
|
||||||
|
000121a0 T _ZwDeleteAtom
|
||||||
|
000121ae T _NtDeleteFile
|
||||||
|
000121ae T _ZwDeleteFile
|
||||||
|
000121bc T _NtDeleteKey
|
||||||
|
000121bc T _ZwDeleteKey
|
||||||
|
000121ca T _NtDeleteObjectAuditAlarm
|
||||||
|
000121ca T _ZwDeleteObjectAuditAlarm
|
||||||
|
000121d8 T _NtDeleteValueKey
|
||||||
|
000121d8 T _ZwDeleteValueKey
|
||||||
|
000121e6 T _NtDeviceIoControlFile
|
||||||
|
000121e6 T _ZwDeviceIoControlFile
|
||||||
|
000121f4 T _NtDisplayString
|
||||||
|
000121f4 T _ZwDisplayString
|
||||||
|
00012202 T _NtDuplicateObject
|
||||||
|
00012202 T _ZwDuplicateObject
|
||||||
|
00012210 T _NtDuplicateToken
|
||||||
|
00012210 T _ZwDuplicateToken
|
||||||
|
0001221e T _NtEnumerateKey
|
||||||
|
0001221e T _ZwEnumerateKey
|
||||||
|
0001222c T _NtEnumerateValueKey
|
||||||
|
0001222c T _ZwEnumerateValueKey
|
||||||
|
0001223a T _NtExtendSection
|
||||||
|
0001223a T _ZwExtendSection
|
||||||
|
00012248 T _NtFindAtom
|
||||||
|
00012248 T _ZwFindAtom
|
||||||
|
00012256 T _NtFlushBuffersFile
|
||||||
|
00012256 T _ZwFlushBuffersFile
|
||||||
|
00012264 T _NtFlushInstructionCache
|
||||||
|
00012264 T _ZwFlushInstructionCache
|
||||||
|
00012272 T _NtFlushKey
|
||||||
|
00012272 T _ZwFlushKey
|
||||||
|
00012280 T _NtFlushVirtualMemory
|
||||||
|
00012280 T _ZwFlushVirtualMemory
|
||||||
|
0001228e T _NtFlushWriteBuffer
|
||||||
|
0001228e T _ZwFlushWriteBuffer
|
||||||
|
0001229c T _NtFreeVirtualMemory
|
||||||
|
0001229c T _ZwFreeVirtualMemory
|
||||||
|
000122aa T _NtFsControlFile
|
||||||
|
000122aa T _ZwFsControlFile
|
||||||
|
000122b8 T _NtGetContextThread
|
||||||
|
000122b8 T _ZwGetContextThread
|
||||||
|
000122c6 T _NtGetPlugPlayEvent
|
||||||
|
000122c6 T _ZwGetPlugPlayEvent
|
||||||
|
000122d4 T _NtGetTickCount
|
||||||
|
000122d4 T _ZwGetTickCount
|
||||||
|
000122e2 T _NtImpersonateClientOfPort
|
||||||
|
000122e2 T _ZwImpersonateClientOfPort
|
||||||
|
000122f0 T _NtImpersonateThread
|
||||||
|
000122f0 T _ZwImpersonateThread
|
||||||
|
000122fe T _NtInitializeRegistry
|
||||||
|
000122fe T _ZwInitializeRegistry
|
||||||
|
0001230c T _NtListenPort
|
||||||
|
0001230c T _ZwListenPort
|
||||||
|
0001231a T _NtLoadDriver
|
||||||
|
0001231a T _ZwLoadDriver
|
||||||
|
00012328 T _NtLoadKey
|
||||||
|
00012328 T _ZwLoadKey
|
||||||
|
00012336 T _NtLoadKey2
|
||||||
|
00012336 T _ZwLoadKey2
|
||||||
|
00012344 T _NtLockFile
|
||||||
|
00012344 T _ZwLockFile
|
||||||
|
00012352 T _NtLockVirtualMemory
|
||||||
|
00012352 T _ZwLockVirtualMemory
|
||||||
|
00012360 T _NtMakeTemporaryObject
|
||||||
|
00012360 T _ZwMakeTemporaryObject
|
||||||
|
0001236e T _NtMapViewOfSection
|
||||||
|
0001236e T _ZwMapViewOfSection
|
||||||
|
0001237c T _NtNotifyChangeDirectoryFile
|
||||||
|
0001237c T _ZwNotifyChangeDirectoryFile
|
||||||
|
0001238a T _NtNotifyChangeKey
|
||||||
|
0001238a T _ZwNotifyChangeKey
|
||||||
|
00012398 T _NtOpenDirectoryObject
|
||||||
|
00012398 T _ZwOpenDirectoryObject
|
||||||
|
000123a6 T _NtOpenEvent
|
||||||
|
000123a6 T _ZwOpenEvent
|
||||||
|
000123b4 T _NtOpenEventPair
|
||||||
|
000123b4 T _ZwOpenEventPair
|
||||||
|
000123c2 T _NtOpenFile
|
||||||
|
000123c2 T _ZwOpenFile
|
||||||
|
000123d0 T _NtOpenIoCompletion
|
||||||
|
000123d0 T _ZwOpenIoCompletion
|
||||||
|
000123de T _NtOpenKey
|
||||||
|
000123de T _ZwOpenKey
|
||||||
|
000123ec T _NtOpenMutant
|
||||||
|
000123ec T _ZwOpenMutant
|
||||||
|
000123fa T _NtOpenObjectAuditAlarm
|
||||||
|
000123fa T _ZwOpenObjectAuditAlarm
|
||||||
|
00012408 T _NtOpenProcess
|
||||||
|
00012408 T _ZwOpenProcess
|
||||||
|
00012416 T _NtOpenProcessToken
|
||||||
|
00012416 T _ZwOpenProcessToken
|
||||||
|
00012424 T _NtOpenSection
|
||||||
|
00012424 T _ZwOpenSection
|
||||||
|
00012432 T _NtOpenSemaphore
|
||||||
|
00012432 T _ZwOpenSemaphore
|
||||||
|
00012440 T _NtOpenSymbolicLinkObject
|
||||||
|
00012440 T _ZwOpenSymbolicLinkObject
|
||||||
|
0001244e T _NtOpenThread
|
||||||
|
0001244e T _ZwOpenThread
|
||||||
|
0001245c T _NtOpenThreadToken
|
||||||
|
0001245c T _ZwOpenThreadToken
|
||||||
|
0001246a T _NtOpenTimer
|
||||||
|
0001246a T _ZwOpenTimer
|
||||||
|
00012478 T _NtPlugPlayControl
|
||||||
|
00012478 T _ZwPlugPlayControl
|
||||||
|
00012486 T _NtPrivilegeCheck
|
||||||
|
00012486 T _ZwPrivilegeCheck
|
||||||
|
00012494 T _NtPrivilegedServiceAuditAlarm
|
||||||
|
00012494 T _ZwPrivilegedServiceAuditAlarm
|
||||||
|
000124a2 T _NtPrivilegeObjectAuditAlarm
|
||||||
|
000124a2 T _ZwPrivilegeObjectAuditAlarm
|
||||||
|
000124b0 T _NtProtectVirtualMemory
|
||||||
|
000124b0 T _ZwProtectVirtualMemory
|
||||||
|
000124be T _NtPulseEvent
|
||||||
|
000124be T _ZwPulseEvent
|
||||||
|
000124cc T _NtQueryInformationAtom
|
||||||
|
000124cc T _ZwQueryInformationAtom
|
||||||
|
000124da T _NtQueryAttributesFile
|
||||||
|
000124da T _ZwQueryAttributesFile
|
||||||
|
000124e8 T _NtQueryDefaultLocale
|
||||||
|
000124e8 T _ZwQueryDefaultLocale
|
||||||
|
000124f6 T _NtQueryDirectoryFile
|
||||||
|
000124f6 T _ZwQueryDirectoryFile
|
||||||
|
00012504 T _NtQueryDirectoryObject
|
||||||
|
00012504 T _ZwQueryDirectoryObject
|
||||||
|
00012512 T _NtQueryEaFile
|
||||||
|
00012512 T _ZwQueryEaFile
|
||||||
|
00012520 T _NtQueryEvent
|
||||||
|
00012520 T _ZwQueryEvent
|
||||||
|
0001252e T _NtQueryFullAttributesFile
|
||||||
|
0001252e T _ZwQueryFullAttributesFile
|
||||||
|
0001253c T _NtQueryInformationFile
|
||||||
|
0001253c T _ZwQueryInformationFile
|
||||||
|
0001254a T _NtQueryIoCompletion
|
||||||
|
0001254a T _ZwQueryIoCompletion
|
||||||
|
00012558 T _NtQueryInformationPort
|
||||||
|
00012558 T _ZwQueryInformationPort
|
||||||
|
00012566 T _NtQueryInformationProcess
|
||||||
|
00012566 T _ZwQueryInformationProcess
|
||||||
|
00012574 T _NtQueryInformationThread
|
||||||
|
00012574 T _ZwQueryInformationThread
|
||||||
|
00012582 T _NtQueryInformationToken
|
||||||
|
00012582 T _ZwQueryInformationToken
|
||||||
|
00012590 T _NtQueryIntervalProfile
|
||||||
|
00012590 T _ZwQueryIntervalProfile
|
||||||
|
0001259e T _NtQueryKey
|
||||||
|
0001259e T _ZwQueryKey
|
||||||
|
000125ac T _NtQueryMultipleValueKey
|
||||||
|
000125ac T _ZwQueryMultipleValueKey
|
||||||
|
000125ba T _NtQueryMutant
|
||||||
|
000125ba T _ZwQueryMutant
|
||||||
|
000125c8 T _NtQueryObject
|
||||||
|
000125c8 T _ZwQueryObject
|
||||||
|
000125d6 T _NtQueryOleDirectoryFile
|
||||||
|
000125d6 T _ZwQueryOleDirectoryFile
|
||||||
|
000125e4 T _NtQueryPerformanceCounter
|
||||||
|
000125e4 T _ZwQueryPerformanceCounter
|
||||||
|
000125f2 T _NtQuerySection
|
||||||
|
000125f2 T _ZwQuerySection
|
||||||
|
00012600 T _NtQuerySecurityObject
|
||||||
|
00012600 T _ZwQuerySecurityObject
|
||||||
|
0001260e T _NtQuerySemaphore
|
||||||
|
0001260e T _ZwQuerySemaphore
|
||||||
|
0001261c T _NtQuerySymbolicLinkObject
|
||||||
|
0001261c T _ZwQuerySymbolicLinkObject
|
||||||
|
0001262a T _NtQuerySystemEnvironmentValue
|
||||||
|
0001262a T _ZwQuerySystemEnvironmentValue
|
||||||
|
00012638 T _NtQuerySystemInformation
|
||||||
|
00012638 T _ZwQuerySystemInformation
|
||||||
|
00012646 T _NtQuerySystemTime
|
||||||
|
00012646 T _ZwQuerySystemTime
|
||||||
|
00012654 T _NtQueryTimer
|
||||||
|
00012654 T _ZwQueryTimer
|
||||||
|
00012662 T _NtQueryTimerResolution
|
||||||
|
00012662 T _ZwQueryTimerResolution
|
||||||
|
00012670 T _NtQueryValueKey
|
||||||
|
00012670 T _ZwQueryValueKey
|
||||||
|
0001267e T _NtQueryVirtualMemory
|
||||||
|
0001267e T _ZwQueryVirtualMemory
|
||||||
|
0001268c T _NtQueryVolumeInformationFile
|
||||||
|
0001268c T _ZwQueryVolumeInformationFile
|
||||||
|
0001269a T _NtQueueApcThread
|
||||||
|
0001269a T _ZwQueueApcThread
|
||||||
|
000126a8 T _NtRaiseException
|
||||||
|
000126a8 T _ZwRaiseException
|
||||||
|
000126b6 T _NtRaiseHardError
|
||||||
|
000126b6 T _ZwRaiseHardError
|
||||||
|
000126c4 T _NtReadFile
|
||||||
|
000126c4 T _ZwReadFile
|
||||||
|
000126d2 T _NtReadFileScatter
|
||||||
|
000126d2 T _ZwReadFileScatter
|
||||||
|
000126e0 T _NtReadRequestData
|
||||||
|
000126e0 T _ZwReadRequestData
|
||||||
|
000126ee T _NtReadVirtualMemory
|
||||||
|
000126ee T _ZwReadVirtualMemory
|
||||||
|
000126fc T _NtRegisterThreadTerminatePort
|
||||||
|
000126fc T _ZwRegisterThreadTerminatePort
|
||||||
|
0001270a T _NtReleaseMutant
|
||||||
|
0001270a T _ZwReleaseMutant
|
||||||
|
00012718 T _NtReleaseSemaphore
|
||||||
|
00012718 T _ZwReleaseSemaphore
|
||||||
|
00012726 T _NtRemoveIoCompletion
|
||||||
|
00012726 T _ZwRemoveIoCompletion
|
||||||
|
00012734 T _NtReplaceKey
|
||||||
|
00012734 T _ZwReplaceKey
|
||||||
|
00012742 T _NtReplyPort
|
||||||
|
00012742 T _ZwReplyPort
|
||||||
|
00012750 T _NtReplyWaitReceivePort
|
||||||
|
00012750 T _ZwReplyWaitReceivePort
|
||||||
|
0001275e T _NtReplyWaitReplyPort
|
||||||
|
0001275e T _ZwReplyWaitReplyPort
|
||||||
|
0001276c T _NtRequestPort
|
||||||
|
0001276c T _ZwRequestPort
|
||||||
|
0001277a T _NtRequestWaitReplyPort
|
||||||
|
0001277a T _ZwRequestWaitReplyPort
|
||||||
|
00012788 T _NtResetEvent
|
||||||
|
00012788 T _ZwResetEvent
|
||||||
|
00012796 T _NtRestoreKey
|
||||||
|
00012796 T _ZwRestoreKey
|
||||||
|
000127a4 T _NtResumeThread
|
||||||
|
000127a4 T _ZwResumeThread
|
||||||
|
000127b2 T _NtSaveKey
|
||||||
|
000127b2 T _ZwSaveKey
|
||||||
|
000127c0 T _NtSetIoCompletion
|
||||||
|
000127c0 T _ZwSetIoCompletion
|
||||||
|
000127ce T _NtSetContextThread
|
||||||
|
000127ce T _ZwSetContextThread
|
||||||
|
000127dc T _NtSetDefaultHardErrorPort
|
||||||
|
000127dc T _ZwSetDefaultHardErrorPort
|
||||||
|
000127ea T _NtSetDefaultLocale
|
||||||
|
000127ea T _ZwSetDefaultLocale
|
||||||
|
000127f8 T _NtSetEaFile
|
||||||
|
000127f8 T _ZwSetEaFile
|
||||||
|
00012806 T _NtSetEvent
|
||||||
|
00012806 T _ZwSetEvent
|
||||||
|
00012814 T _NtSetHighEventPair
|
||||||
|
00012814 T _ZwSetHighEventPair
|
||||||
|
00012822 T _NtSetHighWaitLowEventPair
|
||||||
|
00012822 T _ZwSetHighWaitLowEventPair
|
||||||
|
00012830 T _NtSetInformationFile
|
||||||
|
00012830 T _ZwSetInformationFile
|
||||||
|
0001283e T _NtSetInformationKey
|
||||||
|
0001283e T _ZwSetInformationKey
|
||||||
|
0001284c T _NtSetInformationObject
|
||||||
|
0001284c T _ZwSetInformationObject
|
||||||
|
0001285a T _NtSetInformationProcess
|
||||||
|
0001285a T _ZwSetInformationProcess
|
||||||
|
00012868 T _NtSetInformationThread
|
||||||
|
00012868 T _ZwSetInformationThread
|
||||||
|
00012876 T _NtSetInformationToken
|
||||||
|
00012876 T _ZwSetInformationToken
|
||||||
|
00012884 T _NtSetIntervalProfile
|
||||||
|
00012884 T _ZwSetIntervalProfile
|
||||||
|
00012892 T _NtSetLdtEntries
|
||||||
|
00012892 T _ZwSetLdtEntries
|
||||||
|
000128a0 T _NtSetLowEventPair
|
||||||
|
000128a0 T _ZwSetLowEventPair
|
||||||
|
000128ae T _NtSetLowWaitHighEventPair
|
||||||
|
000128ae T _ZwSetLowWaitHighEventPair
|
||||||
|
000128bc T _NtSetSecurityObject
|
||||||
|
000128bc T _ZwSetSecurityObject
|
||||||
|
000128ca T _NtSetSystemEnvironmentValue
|
||||||
|
000128ca T _ZwSetSystemEnvironmentValue
|
||||||
|
000128d8 T _NtSetSystemInformation
|
||||||
|
000128d8 T _ZwSetSystemInformation
|
||||||
|
000128e6 T _NtSetSystemPowerState
|
||||||
|
000128e6 T _ZwSetSystemPowerState
|
||||||
|
000128f4 T _NtSetSystemTime
|
||||||
|
000128f4 T _ZwSetSystemTime
|
||||||
|
00012902 T _NtSetTimer
|
||||||
|
00012902 T _ZwSetTimer
|
||||||
|
00012910 T _NtSetTimerResolution
|
||||||
|
00012910 T _ZwSetTimerResolution
|
||||||
|
0001291e T _NtSetValueKey
|
||||||
|
0001291e T _ZwSetValueKey
|
||||||
|
0001292c T _NtSetVolumeInformationFile
|
||||||
|
0001292c T _ZwSetVolumeInformationFile
|
||||||
|
0001293a T _NtShutdownSystem
|
||||||
|
0001293a T _ZwShutdownSystem
|
||||||
|
00012948 T _NtSignalAndWaitForSingleObject
|
||||||
|
00012948 T _ZwSignalAndWaitForSingleObject
|
||||||
|
00012956 T _NtStartProfile
|
||||||
|
00012956 T _ZwStartProfile
|
||||||
|
00012964 T _NtStopProfile
|
||||||
|
00012964 T _ZwStopProfile
|
||||||
|
00012972 T _NtSuspendThread
|
||||||
|
00012972 T _ZwSuspendThread
|
||||||
|
00012980 T _NtSystemDebugControl
|
||||||
|
00012980 T _ZwSystemDebugControl
|
||||||
|
0001298e T _NtTerminateProcess
|
||||||
|
0001298e T _ZwTerminateProcess
|
||||||
|
0001299c T _NtTerminateThread
|
||||||
|
0001299c T _ZwTerminateThread
|
||||||
|
000129aa T _NtTestAlert
|
||||||
|
000129aa T _ZwTestAlert
|
||||||
|
000129b8 T _NtUnloadDriver
|
||||||
|
000129b8 T _ZwUnloadDriver
|
||||||
|
000129c6 T _NtUnloadKey
|
||||||
|
000129c6 T _ZwUnloadKey
|
||||||
|
000129d4 T _NtUnlockFile
|
||||||
|
000129d4 T _ZwUnlockFile
|
||||||
|
000129e2 T _NtUnlockVirtualMemory
|
||||||
|
000129e2 T _ZwUnlockVirtualMemory
|
||||||
|
000129f0 T _NtUnmapViewOfSection
|
||||||
|
000129f0 T _ZwUnmapViewOfSection
|
||||||
|
000129fe T _NtVdmControl
|
||||||
|
000129fe T _ZwVdmControl
|
||||||
|
00012a0c T _NtWaitForMultipleObjects
|
||||||
|
00012a0c T _ZwWaitForMultipleObjects
|
||||||
|
00012a1a T _NtWaitForSingleObject
|
||||||
|
00012a1a T _ZwWaitForSingleObject
|
||||||
|
00012a28 T _NtWaitHighEventPair
|
||||||
|
00012a28 T _ZwWaitHighEventPair
|
||||||
|
00012a36 T _NtWaitLowEventPair
|
||||||
|
00012a36 T _ZwWaitLowEventPair
|
||||||
|
00012a44 T _NtWriteFile
|
||||||
|
00012a44 T _ZwWriteFile
|
||||||
|
00012a52 T _NtWriteFileGather
|
||||||
|
00012a52 T _ZwWriteFileGather
|
||||||
|
00012a60 T _NtWriteRequestData
|
||||||
|
00012a60 T _ZwWriteRequestData
|
||||||
|
00012a6e T _NtWriteVirtualMemory
|
||||||
|
00012a6e T _ZwWriteVirtualMemory
|
||||||
|
00012a7c T _NtW32Call
|
||||||
|
00012a7c T _ZwW32Call
|
||||||
|
00012a8a T _NtCreateChannel
|
||||||
|
00012a8a T _ZwCreateChannel
|
||||||
|
00012a98 T _NtListenChannel
|
||||||
|
00012a98 T _ZwListenChannel
|
||||||
|
00012aa6 T _NtOpenChannel
|
||||||
|
00012aa6 T _ZwOpenChannel
|
||||||
|
00012ab4 T _NtReplyWaitSendChannel
|
||||||
|
00012ab4 T _ZwReplyWaitSendChannel
|
||||||
|
00012ac2 T _NtSendWaitReplyChannel
|
||||||
|
00012ac2 T _ZwSendWaitReplyChannel
|
||||||
|
00012ad0 T _NtSetContextChannel
|
||||||
|
00012ad0 T _ZwSetContextChannel
|
||||||
|
00012ade T _NtYieldExecution
|
||||||
|
00012ade T _ZwYieldExecution
|
||||||
|
00012aec T etext
|
||||||
|
00013000 d .data
|
||||||
|
00013000 d .data
|
||||||
|
00013000 d .data
|
||||||
|
00013000 d ___HeapDefaultBuckets
|
||||||
|
00013080 b .bss
|
||||||
|
00013080 b .bss
|
||||||
|
00013080 b .bss
|
||||||
|
00013080 b .bss
|
||||||
|
00013080 b .bss
|
||||||
|
00013080 b .bss
|
||||||
|
00013080 d .data
|
||||||
|
00013080 d .data
|
||||||
|
00013080 d .data
|
||||||
|
00013080 d .data
|
||||||
|
00013080 d .data
|
||||||
|
00013080 d .data
|
||||||
|
00013080 d .data
|
||||||
|
00013080 b _LastError
|
||||||
|
00013080 D _edata
|
||||||
|
00013084 b .bss
|
||||||
|
00013084 b .bss
|
||||||
|
00013084 b .bss
|
||||||
|
00013084 b .bss
|
||||||
|
00013084 B ___ProcessHeap
|
||||||
|
00013088 B end
|
32
reactos/doc/cacheman.txt
Normal file
32
reactos/doc/cacheman.txt
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
- Cache Manager
|
||||||
|
|
||||||
|
This document describes the current implementation of the cache manager.
|
||||||
|
|
||||||
|
- Description
|
||||||
|
|
||||||
|
In its current state the CM (cache manager) only includes primitives to
|
||||||
|
cache disk blocks, this is useful for filesystem metadata but it requires an
|
||||||
|
additional copy operation when reading files from cache. This will be fixed.
|
||||||
|
|
||||||
|
Each disk drive with data in the cache has an associated DCCB (Device Cache
|
||||||
|
Control Block) which details all the blocks from the device in memory. If a
|
||||||
|
filesystem requires cache services for a device it must call CbInitDccb to
|
||||||
|
initialize this structure.
|
||||||
|
|
||||||
|
Each block with data from a device has an associated CCB (Cache Control
|
||||||
|
Block) with a pointer to the physical memory used to hold the block, and
|
||||||
|
various state and locking information. When a filesystem requires a block
|
||||||
|
from the device it calls CbAcquireForRead or CbAcquireForWrite which ensure
|
||||||
|
the data for the block is uptodate (loading it from disk if necessary) and
|
||||||
|
return a pointer to the associated CCB. When a filesystem has finished with
|
||||||
|
a block it calls CbReleaseFromRead or CbReleaseFromWrite, it is important to
|
||||||
|
call these functions because the CM can only release blocks from the cache
|
||||||
|
if they have no active readers or writers. The CM also enforces cache
|
||||||
|
consistency by ensuring that while multiple threads can be reading a block
|
||||||
|
simultaneously, there is only ever one active writers.
|
||||||
|
|
||||||
|
The CM provides no support for deadlock prevention/detection as it has no
|
||||||
|
knowledge of the layout of a a filesystem (nor should it have).
|
||||||
|
|
||||||
|
- TODO
|
||||||
|
|
2
reactos/drivers/dd/event/dirs
Normal file
2
reactos/drivers/dd/event/dirs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
DIRS=exe \
|
||||||
|
sys
|
168
reactos/drivers/dd/event/exe/eventtes.c
Normal file
168
reactos/drivers/dd/event/exe/eventtes.c
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1996 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
EventTest.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Simple console test app demonstrating how a Win32 app can share
|
||||||
|
an event object with a kernel-mode driver. For more information
|
||||||
|
on using Event Objects at the application level see the Win32 SDK.
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Jeff Midkiff (jeffmi) 23-Jul-96
|
||||||
|
|
||||||
|
Enviroment:
|
||||||
|
|
||||||
|
User Mode
|
||||||
|
|
||||||
|
Revision History:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// INCLUDES
|
||||||
|
//
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <winioctl.h>
|
||||||
|
#include <conio.h>
|
||||||
|
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MAIN
|
||||||
|
//
|
||||||
|
void __cdecl
|
||||||
|
main(
|
||||||
|
int argc,
|
||||||
|
char ** argv
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOL bStatus;
|
||||||
|
HANDLE hDevice;
|
||||||
|
ULONG ulReturnedLength;
|
||||||
|
|
||||||
|
SET_EVENT setEvent;
|
||||||
|
FLOAT fDelay;
|
||||||
|
|
||||||
|
|
||||||
|
if ( (argc < 2) || (argv[1] == NULL) ) {
|
||||||
|
printf("event <delay>\n");
|
||||||
|
printf("\twhere <delay> = time to delay the event signal in seconds.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
sscanf( argv[1], "%f", &fDelay );
|
||||||
|
|
||||||
|
//
|
||||||
|
// open the device
|
||||||
|
//
|
||||||
|
hDevice = CreateFile(
|
||||||
|
"\\\\.\\EVENT", // lpFileName
|
||||||
|
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
|
||||||
|
NULL, // lpSecurityAttributes
|
||||||
|
OPEN_EXISTING, // dwCreationDistribution
|
||||||
|
0, // dwFlagsAndAttributes
|
||||||
|
NULL // hTemplateFile
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hDevice == INVALID_HANDLE_VALUE) {
|
||||||
|
printf("CreateFile error = %d\n", GetLastError() );
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// set the event signal delay
|
||||||
|
//
|
||||||
|
setEvent.DueTime.QuadPart = -((LONGLONG)(fDelay * 10.0E6));// use relative time for this sample
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// test the driver for bad event handles
|
||||||
|
//
|
||||||
|
setEvent.hEvent = NULL;
|
||||||
|
bStatus = DeviceIoControl(
|
||||||
|
hDevice, // Handle to device
|
||||||
|
IOCTL_SET_EVENT, // IO Control code
|
||||||
|
&setEvent, // Input Buffer to driver.
|
||||||
|
SIZEOF_SETEVENT, // Length of input buffer in bytes.
|
||||||
|
NULL, // Output Buffer from driver.
|
||||||
|
0, // Length of output buffer in bytes.
|
||||||
|
&ulReturnedLength, // Bytes placed in buffer.
|
||||||
|
NULL // synchronous call
|
||||||
|
);
|
||||||
|
if ( !bStatus ) {
|
||||||
|
printf("Bad handle TEST returned code %d.\n\n", GetLastError() );
|
||||||
|
} else {
|
||||||
|
printf("we should never get here\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
setEvent.hEvent = CreateEvent(
|
||||||
|
NULL, // lpEventAttributes
|
||||||
|
TRUE, // bManualReset
|
||||||
|
FALSE, // bInitialState
|
||||||
|
NULL // lpName
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if ( !setEvent.hEvent ) {
|
||||||
|
printf("CreateEvent error = %d\n", GetLastError() );
|
||||||
|
} else {
|
||||||
|
|
||||||
|
printf("Event HANDLE = 0x%x\n", setEvent.hEvent );
|
||||||
|
printf("Press any key to exit.\n");
|
||||||
|
while( !_kbhit() ) {
|
||||||
|
bStatus = DeviceIoControl(
|
||||||
|
hDevice, // Handle to device
|
||||||
|
IOCTL_SET_EVENT, // IO Control code
|
||||||
|
&setEvent, // Input Buffer to driver.
|
||||||
|
SIZEOF_SETEVENT, // Length of input buffer in bytes.
|
||||||
|
NULL, // Output Buffer from driver.
|
||||||
|
0, // Length of output buffer in bytes.
|
||||||
|
&ulReturnedLength, // Bytes placed in buffer.
|
||||||
|
NULL // synchronous call
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !bStatus ) {
|
||||||
|
printf("Ioctl failed with code %d\n", GetLastError() );
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
printf("Waiting for Event...\n");
|
||||||
|
|
||||||
|
WaitForSingleObject(setEvent.hEvent,
|
||||||
|
INFINITE );
|
||||||
|
|
||||||
|
printf("Event signalled.\n\n");
|
||||||
|
|
||||||
|
ResetEvent( setEvent.hEvent);
|
||||||
|
//printf("Event reset.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// close the driver
|
||||||
|
//
|
||||||
|
if ( !CloseHandle(hDevice) ) {
|
||||||
|
printf("Failed to close device.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// EOF
|
7
reactos/drivers/dd/event/exe/makefile
Normal file
7
reactos/drivers/dd/event/exe/makefile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#
|
||||||
|
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
|
||||||
|
# file to this component. This file merely indirects to the real make file
|
||||||
|
# that is shared by all the driver components of the Windows NT DDK
|
||||||
|
#
|
||||||
|
|
||||||
|
!INCLUDE $(NTMAKEENV)\makefile.def
|
10
reactos/drivers/dd/event/exe/sources
Normal file
10
reactos/drivers/dd/event/exe/sources
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
TARGETNAME=event
|
||||||
|
TARGETPATH=$(BASEDIR)\lib
|
||||||
|
TARGETTYPE=PROGRAM
|
||||||
|
|
||||||
|
INCLUDES=..\sys
|
||||||
|
|
||||||
|
SOURCES=eventtest.c
|
||||||
|
|
||||||
|
UMTYPE=console
|
||||||
|
UMBASE=0x100000
|
50
reactos/drivers/dd/event/readme.txt
Normal file
50
reactos/drivers/dd/event/readme.txt
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
|
||||||
|
This sample demonstrates one way that a Windows NT kernel-mode device driver
|
||||||
|
can share and explicitly signal an Event Object with a Win32 application.
|
||||||
|
It is composed of two parts, a Windows NT kernel-mode device driver and a Win32
|
||||||
|
console test application. Both are built using the Windows NT DDK.
|
||||||
|
|
||||||
|
|
||||||
|
Instructions:
|
||||||
|
-------------
|
||||||
|
|
||||||
|
1) Build the driver and test application in either the FREE or CHECKED build environment:
|
||||||
|
|
||||||
|
BLD
|
||||||
|
|
||||||
|
Both the driver and application are put in %NTDDK%\LIB\*\FREE | CHECKED on your build machine.
|
||||||
|
|
||||||
|
|
||||||
|
2) Copy the newly built driver to your Target machine's %SystemRoot%\system32\drivers
|
||||||
|
directory. Copy the newly built application to your target machine.
|
||||||
|
Also copy the EVENT.INI file to your Target machine.
|
||||||
|
|
||||||
|
|
||||||
|
3) Update the Target machine's Registry by running REGINI.EXE on the EVENT.INI file, i.e.:
|
||||||
|
|
||||||
|
REGINI EVENT.INI
|
||||||
|
|
||||||
|
This adds a driver key under the
|
||||||
|
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services tree in the Registry.
|
||||||
|
You can verify this by running REGEDIT32.EXE and looking at the \Event key.
|
||||||
|
|
||||||
|
|
||||||
|
4) Reboot the Target machine for the Registry changes to take effect.
|
||||||
|
Your driver will not load until you reboot.
|
||||||
|
|
||||||
|
|
||||||
|
5) Load the driver from the command line:
|
||||||
|
|
||||||
|
NET START EVENT
|
||||||
|
|
||||||
|
|
||||||
|
6) Run the test app from the command line:
|
||||||
|
|
||||||
|
EVENT <DELAY>
|
||||||
|
|
||||||
|
where DELAY = time to delay the Event signal in seconds.
|
||||||
|
|
||||||
|
|
||||||
|
7) Unload the driver from the command line:
|
||||||
|
|
||||||
|
NET STOP EVENT
|
447
reactos/drivers/dd/event/sys/event.c
Normal file
447
reactos/drivers/dd/event/sys/event.c
Normal file
|
@ -0,0 +1,447 @@
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1996 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Event.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
This sample demonstrates one way that a Windows NT kernel-mode driver
|
||||||
|
can share and explicitly signal an Event Object with a Win32 application.
|
||||||
|
|
||||||
|
This sample uses the following method:
|
||||||
|
The application creates an event object using CreateEvent().
|
||||||
|
The app passes the event handle to the driver in a private IOCTL.
|
||||||
|
The driver is running in the app's thread context during the IOCTL so
|
||||||
|
there is a valid user-mode handle at that time.
|
||||||
|
The driver dereferences the user-mode handle into system space & saves
|
||||||
|
the new system handle for later use.
|
||||||
|
The driver signals the event via KeSetEvent() at IRQL <= DISPATCH_LEVEL.
|
||||||
|
The driver MUST delete any driver references to the event object at
|
||||||
|
Unload time.
|
||||||
|
|
||||||
|
An alternative method would be to create a named event in the driver via
|
||||||
|
IoCreateNotificationEvent and then open the event in user mode. This API
|
||||||
|
however is new to Windows NT 4.0 so you can not use this method in your
|
||||||
|
NT 3.5x drivers.
|
||||||
|
|
||||||
|
Note that this sample's event can be signalled (almost) at will from within
|
||||||
|
the driver. A different event signal can be set when the driver is setup to
|
||||||
|
do asynchronous I/O, and it is opened with FILE_FLAG_OVERLAPPED, and an
|
||||||
|
event handle is passed down in an OVERLAPPED struct from the app's Read,
|
||||||
|
Write, or DeviceIoControl. This different event signal is set by the I/O
|
||||||
|
Manager when the driver calls IoCompleteRequest on a pending Irp. This type
|
||||||
|
of Irp completion signal is not the purpose of this sample, hence the lack of
|
||||||
|
Irp queing.
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Jeff Midkiff (jeffmi) 23-Jul-96
|
||||||
|
|
||||||
|
Enviroment:
|
||||||
|
|
||||||
|
Kernel Mode Only
|
||||||
|
|
||||||
|
Revision History:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// INCLUDES
|
||||||
|
//
|
||||||
|
#include "ntddk.h"
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// DEFINES
|
||||||
|
//
|
||||||
|
#define USER_NAME L"\\DosDevices\\EVENT"
|
||||||
|
#define SYSTEM_NAME L"\\Device\\EVENT"
|
||||||
|
|
||||||
|
//
|
||||||
|
// DATA
|
||||||
|
//
|
||||||
|
typedef struct _DEVICE_EXTENSION {
|
||||||
|
KDPC Dpc;
|
||||||
|
KTIMER Timer;
|
||||||
|
HANDLE hEvent;
|
||||||
|
|
||||||
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// PROTOS
|
||||||
|
//
|
||||||
|
NTSTATUS
|
||||||
|
DriverEntry(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PUNICODE_STRING RegistryPath
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
Unload(
|
||||||
|
IN PDRIVER_OBJECT DriverObject
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
Dispatch(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CustomTimerDPC(
|
||||||
|
IN PKDPC Dpc,
|
||||||
|
IN PVOID DeferredContext,
|
||||||
|
IN PVOID SystemArgument1,
|
||||||
|
IN PVOID SystemArgument2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
DriverEntry(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PUNICODE_STRING RegistryPath
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This routine gets called by the system to initialize the driver.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
DriverObject - the system supplied driver object.
|
||||||
|
RegistryPath - the system supplied registry path for this driver.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
PDEVICE_OBJECT pDeviceObject;
|
||||||
|
PDEVICE_EXTENSION pDeviceExtension;
|
||||||
|
|
||||||
|
UNICODE_STRING usSystemName;
|
||||||
|
UNICODE_STRING usUserName;
|
||||||
|
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
|
||||||
|
KdPrint(("Event!DriverEntry - IN\n"));
|
||||||
|
|
||||||
|
//
|
||||||
|
// create the device object
|
||||||
|
//
|
||||||
|
RtlInitUnicodeString( &usSystemName, SYSTEM_NAME );
|
||||||
|
|
||||||
|
status = IoCreateDevice(
|
||||||
|
DriverObject, // DriverObject
|
||||||
|
sizeof( DEVICE_EXTENSION ), // DeviceExtensionSize
|
||||||
|
&usSystemName, // DeviceName
|
||||||
|
FILE_DEVICE_UNKNOWN, // DeviceType
|
||||||
|
0, // DeviceCharacteristics
|
||||||
|
TRUE, // Exclusive
|
||||||
|
&pDeviceObject // DeviceObject
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !NT_SUCCESS(status) ) {
|
||||||
|
KdPrint(("\tIoCreateDevice returned 0x%x\n", status));
|
||||||
|
|
||||||
|
return( status );
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up dispatch entry points for the driver.
|
||||||
|
//
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] =
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Dispatch;
|
||||||
|
DriverObject->DriverUnload = Unload;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a symbolic link into user mode for the driver.
|
||||||
|
//
|
||||||
|
RtlInitUnicodeString( &usUserName, USER_NAME );
|
||||||
|
status = IoCreateSymbolicLink( &usUserName, &usSystemName );
|
||||||
|
|
||||||
|
if ( !NT_SUCCESS(status) ) {
|
||||||
|
IoDeleteDevice( pDeviceObject );
|
||||||
|
KdPrint(("\tIoCreateSymbolicLink returned 0x%x\n", status));
|
||||||
|
|
||||||
|
return( status );
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// establish user-buffer access method
|
||||||
|
//
|
||||||
|
pDeviceObject->Flags |= DO_BUFFERED_IO;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// setup the device extension
|
||||||
|
//
|
||||||
|
pDeviceExtension = pDeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
KeInitializeDpc(
|
||||||
|
&pDeviceExtension->Dpc, // Dpc
|
||||||
|
CustomTimerDPC, // DeferredRoutine
|
||||||
|
pDeviceObject // DeferredContext
|
||||||
|
);
|
||||||
|
|
||||||
|
KeInitializeTimer(
|
||||||
|
&pDeviceExtension->Timer // Timer
|
||||||
|
);
|
||||||
|
|
||||||
|
pDeviceExtension->hEvent = NULL;
|
||||||
|
|
||||||
|
KdPrint(("Event!DriverEntry - OUT\n"));
|
||||||
|
|
||||||
|
return( status );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
Unload(
|
||||||
|
IN PDRIVER_OBJECT DriverObject
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This routine gets called to remove the driver from the system.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
DriverObject - the system supplied driver object.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
PDEVICE_OBJECT pDeviceObject = DriverObject->DeviceObject;
|
||||||
|
PDEVICE_EXTENSION pDeviceExtension = pDeviceObject->DeviceExtension;
|
||||||
|
UNICODE_STRING usUserName;
|
||||||
|
|
||||||
|
|
||||||
|
KdPrint(("Event!Unload\n"));
|
||||||
|
|
||||||
|
//
|
||||||
|
// dereference the event object or it will NEVER go away until reboot
|
||||||
|
//
|
||||||
|
if ( pDeviceExtension->hEvent )
|
||||||
|
ObDereferenceObject( pDeviceExtension->hEvent );
|
||||||
|
|
||||||
|
// Delete the user-mode symbolic link.
|
||||||
|
RtlInitUnicodeString( &usUserName, USER_NAME );
|
||||||
|
IoDeleteSymbolicLink( &usUserName );
|
||||||
|
|
||||||
|
// Delete the DeviceObject
|
||||||
|
IoDeleteDevice( pDeviceObject );
|
||||||
|
|
||||||
|
return( STATUS_SUCCESS );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
Dispatch(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This device control dispatcher handles IOCTLs.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
DeviceObject - Context for the activity.
|
||||||
|
Irp - The device control argument block.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
PDEVICE_EXTENSION pDeviceExtension;
|
||||||
|
PIO_STACK_LOCATION pIrpStack;
|
||||||
|
PSET_EVENT pSetEvent;
|
||||||
|
|
||||||
|
ULONG ulInformation = 0L;
|
||||||
|
NTSTATUS status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
|
|
||||||
|
KdPrint(("Event!Dispatch - IN\n"));
|
||||||
|
|
||||||
|
pDeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
pIrpStack = IoGetCurrentIrpStackLocation( Irp );
|
||||||
|
|
||||||
|
switch( pIrpStack->MajorFunction )
|
||||||
|
{
|
||||||
|
case IRP_MJ_CREATE:
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
|
KdPrint(("\t%s\n", (IRP_MJ_CREATE == pIrpStack->MajorFunction) ? "IRP_MJ_CREATE" : "IRP_MJ_CLOSE"));
|
||||||
|
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_DEVICE_CONTROL:
|
||||||
|
switch( pIrpStack->Parameters.DeviceIoControl.IoControlCode )
|
||||||
|
{
|
||||||
|
case IOCTL_SET_EVENT:
|
||||||
|
KdPrint(("\tIOCTL_SET_EVENT\n"));
|
||||||
|
|
||||||
|
if ( pIrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_SETEVENT ) {
|
||||||
|
// Parameters are invalid
|
||||||
|
KdPrint(("\tSTATUS_INVALID_PARAMETER\n"));
|
||||||
|
|
||||||
|
status = STATUS_INVALID_PARAMETER;
|
||||||
|
} else {
|
||||||
|
pSetEvent = (PSET_EVENT)Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
KdPrint(("\tuser-mode HANDLE = 0x%x\n", pSetEvent->hEvent ));
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle( pSetEvent->hEvent,
|
||||||
|
SYNCHRONIZE,
|
||||||
|
NULL,
|
||||||
|
KernelMode,
|
||||||
|
&pDeviceExtension->hEvent,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if ( !NT_SUCCESS(status) ) {
|
||||||
|
|
||||||
|
KdPrint(("\tUnable to reference User-Mode Event object, Error = 0x%x\n", status));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
KdPrint(("\tkernel-mode HANDLE = 0x%x\n", pDeviceExtension->hEvent ));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start the timer to run the CustomTimerDPC in DueTime seconds to
|
||||||
|
// simulate an interrupt (which would queue a DPC).
|
||||||
|
// The user's event object is signaled in the DPC.
|
||||||
|
//
|
||||||
|
|
||||||
|
// ensure relative time for this sample
|
||||||
|
if ( pSetEvent->DueTime.QuadPart > 0 )
|
||||||
|
pSetEvent->DueTime.QuadPart = -(pSetEvent->DueTime.QuadPart);
|
||||||
|
KdPrint(("\tDueTime = %d\n", pSetEvent->DueTime.QuadPart ));
|
||||||
|
|
||||||
|
KeSetTimer(
|
||||||
|
&pDeviceExtension->Timer, // Timer
|
||||||
|
pSetEvent->DueTime, // DueTime
|
||||||
|
&pDeviceExtension->Dpc // Dpc
|
||||||
|
);
|
||||||
|
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// should never hit this
|
||||||
|
ASSERT(0);
|
||||||
|
status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
} // switch IoControlCode
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// should never hit this
|
||||||
|
ASSERT(0);
|
||||||
|
status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
} // switch MajorFunction
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// complete the Irp
|
||||||
|
//
|
||||||
|
Irp->IoStatus.Status = status;
|
||||||
|
Irp->IoStatus.Information = ulInformation;
|
||||||
|
IoCompleteRequest( Irp, IO_NO_INCREMENT );
|
||||||
|
|
||||||
|
KdPrint(("Event!Dispatch - OUT\n"));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CustomTimerDPC(
|
||||||
|
IN PKDPC Dpc,
|
||||||
|
IN PVOID DeferredContext,
|
||||||
|
IN PVOID SystemArgument1,
|
||||||
|
IN PVOID SystemArgument2
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This is the DPC associated with this drivers Timer object setup in DriverEntry.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Dpc - our DPC object associated with our Timer
|
||||||
|
DeferredContext - Context for the DPC that we setup in DriverEntry
|
||||||
|
SystemArgument1 -
|
||||||
|
SystemArgument2 -
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
Nothing.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
PDEVICE_OBJECT pDeviceObject = DeferredContext;
|
||||||
|
PDEVICE_EXTENSION pDeviceExtension = pDeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
|
||||||
|
KdPrint(("Event!CustomTimerDPC - IN\n"));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Signal the Event created user-mode
|
||||||
|
//
|
||||||
|
// Note:
|
||||||
|
// Do not call KeSetEvent from your ISR;
|
||||||
|
// you must call it at IRQL <= DISPATCH_LEVEL.
|
||||||
|
// Your ISR should queue a DPC and the DPC can
|
||||||
|
// then call KeSetEvent on the ISR's behalf.
|
||||||
|
//
|
||||||
|
KeSetEvent((PKEVENT)pDeviceExtension->hEvent,// Event
|
||||||
|
0, // Increment
|
||||||
|
FALSE // Wait
|
||||||
|
);
|
||||||
|
|
||||||
|
// there is no Irp to complete here
|
||||||
|
|
||||||
|
KdPrint(("Event!CustomTimerDPC - OUT\n"));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// EOF
|
43
reactos/drivers/dd/event/sys/event.h
Normal file
43
reactos/drivers/dd/event/sys/event.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1996 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Event.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Jeff Midkiff (jeffmi) 23-Jul-96
|
||||||
|
|
||||||
|
Enviroment:
|
||||||
|
|
||||||
|
|
||||||
|
Revision History:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef __EVENT__
|
||||||
|
#define __EVENT__
|
||||||
|
|
||||||
|
|
||||||
|
#include "devioctl.h"
|
||||||
|
|
||||||
|
typedef struct _SET_EVENT
|
||||||
|
{
|
||||||
|
HANDLE hEvent;
|
||||||
|
LARGE_INTEGER DueTime; // requested DueTime in 100-nanosecond units
|
||||||
|
|
||||||
|
} SET_EVENT, *PSET_EVENT;
|
||||||
|
|
||||||
|
#define SIZEOF_SETEVENT sizeof(SET_EVENT)
|
||||||
|
|
||||||
|
|
||||||
|
#define IOCTL_SET_EVENT \
|
||||||
|
CTL_CODE( FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS )
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __EVENT__
|
7
reactos/drivers/dd/event/sys/event.ini
Normal file
7
reactos/drivers/dd/event/sys/event.ini
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
; note - the service name matches the driver's file (.sys) name
|
||||||
|
|
||||||
|
\Registry\Machine\System\CurrentControlSet\Services\Event
|
||||||
|
Type = REG_DWORD 0x00000001
|
||||||
|
Start = REG_DWORD 0x00000003
|
||||||
|
Group = Extended Base
|
||||||
|
ErrorControl = REG_DWORD 0x00000001
|
11
reactos/drivers/dd/event/sys/event.rc
Normal file
11
reactos/drivers/dd/event/sys/event.rc
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <ntverp.h>
|
||||||
|
|
||||||
|
#define VER_FILETYPE VFT_DRV
|
||||||
|
#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
|
||||||
|
#define VER_FILEDESCRIPTION_STR "Sample Event Driver"
|
||||||
|
#define VER_INTERNALNAME_STR "event.sys"
|
||||||
|
|
||||||
|
#include "common.ver"
|
||||||
|
|
7
reactos/drivers/dd/event/sys/makefile
Normal file
7
reactos/drivers/dd/event/sys/makefile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#
|
||||||
|
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
|
||||||
|
# file to this component. This file merely indirects to the real make file
|
||||||
|
# that is shared by all the driver components of the Windows NT DDK
|
||||||
|
#
|
||||||
|
|
||||||
|
!INCLUDE $(NTMAKEENV)\makefile.def
|
6
reactos/drivers/dd/event/sys/sources
Normal file
6
reactos/drivers/dd/event/sys/sources
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
TARGETNAME=event
|
||||||
|
TARGETPATH=$(BASEDIR)\lib
|
||||||
|
TARGETTYPE=DRIVER
|
||||||
|
|
||||||
|
SOURCES=event.c \
|
||||||
|
event.rc
|
1826
reactos/drivers/dd/ide/ide.c
Normal file
1826
reactos/drivers/dd/ide/ide.c
Normal file
File diff suppressed because it is too large
Load diff
209
reactos/drivers/dd/ide/ide.h
Normal file
209
reactos/drivers/dd/ide/ide.h
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
//
|
||||||
|
// IDE.H - defines and typedefs for the IDE Driver module.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __IDE_H
|
||||||
|
#define __IDE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IDE_MAXIMUM_DEVICES 8
|
||||||
|
|
||||||
|
#define IDE_MAX_NAME_LENGTH 50
|
||||||
|
#define IDE_NT_ROOTDIR_NAME "\\Device"
|
||||||
|
#define IDE_NT_DEVICE_NAME "\\HardDrive"
|
||||||
|
#define IDE_NT_PARTITION_NAME "\\Partition"
|
||||||
|
#define IDE_WIN32_DEVICE_NAME "\\DosDevices\\IDE"
|
||||||
|
#define IDE_DRIVER_NAME "IDEDRIVER"
|
||||||
|
|
||||||
|
#define IDE_SECTOR_BUF_SZ 512
|
||||||
|
#define IDE_MAX_SECTORS_PER_XFER 256
|
||||||
|
#define IDE_MAX_RESET_RETRIES 10000
|
||||||
|
#define IDE_MAX_WRITE_RETRIES 1000
|
||||||
|
#define IDE_MAX_BUSY_RETRIES 100
|
||||||
|
#define IDE_MAX_DRQ_RETRIES 1000
|
||||||
|
|
||||||
|
#define IDE_REG_ALT_STATUS 0x0006
|
||||||
|
#define IDE_REG_DEV_CNTRL 0x0006 /* device control register */
|
||||||
|
#define IDE_DC_SRST 0x04 /* drive reset (both drives) */
|
||||||
|
#define IDE_DC_nIEN 0x02 /* IRQ enable (active low) */
|
||||||
|
#define IDE_REG_DRV_ADDR 0x0007
|
||||||
|
#define IDE_REG_DATA_PORT 0x0000
|
||||||
|
#define IDE_REG_ERROR 0x0001 /* error register */
|
||||||
|
#define IDE_ER_AMNF 0x01 /* addr mark not found */
|
||||||
|
#define IDE_ER_TK0NF 0x02 /* track 0 not found */
|
||||||
|
#define IDE_ER_ABRT 0x04 /* command aborted */
|
||||||
|
#define IDE_ER_MCR 0x08 /* media change requested */
|
||||||
|
#define IDE_ER_IDNF 0x10 /* ID not found */
|
||||||
|
#define IDE_ER_MC 0x20 /* Media changed */
|
||||||
|
#define IDE_ER_UNC 0x40 /* Uncorrectable data error */
|
||||||
|
#define IDE_REG_PRECOMP 0x0001
|
||||||
|
#define IDE_REG_SECTOR_CNT 0x0002
|
||||||
|
#define IDE_REG_SECTOR_NUM 0x0003
|
||||||
|
#define IDE_REG_CYL_LOW 0x0004
|
||||||
|
#define IDE_REG_CYL_HIGH 0x0005
|
||||||
|
#define IDE_REG_DRV_HEAD 0x0006
|
||||||
|
#define IDE_DH_FIXED 0xA0
|
||||||
|
#define IDE_DH_LBA 0x40
|
||||||
|
#define IDE_DH_HDMASK 0x0F
|
||||||
|
#define IDE_DH_DRV0 0x00
|
||||||
|
#define IDE_DH_DRV1 0x10
|
||||||
|
#define IDE_REG_STATUS 0x0007
|
||||||
|
#define IDE_SR_BUSY 0x80
|
||||||
|
#define IDE_SR_DRDY 0x40
|
||||||
|
#define IDE_SR_DRQ 0x08
|
||||||
|
#define IDE_SR_ERR 0x01
|
||||||
|
#define IDE_REG_COMMAND 0x0007
|
||||||
|
#define IDE_CMD_READ 0x20
|
||||||
|
#define IDE_CMD_READ_RETRY 0x21
|
||||||
|
#define IDE_CMD_WRITE 0x30
|
||||||
|
#define IDE_CMD_WRITE_RETRY 0x31
|
||||||
|
#define IDE_CMD_IDENT_DRV 0xEC
|
||||||
|
|
||||||
|
//
|
||||||
|
// Access macros for command registers
|
||||||
|
// Each macro takes an address of the command port block, and data
|
||||||
|
//
|
||||||
|
#define IDEReadError(Address) (inb_p((Address) + IDE_REG_ERROR))
|
||||||
|
#define IDEWritePrecomp(Address, Data) (outb_p((Address) + IDE_REG_PRECOMP, (Data)))
|
||||||
|
#define IDEReadSectorCount(Address) (inb_p((Address) + IDE_REG_SECTOR_CNT))
|
||||||
|
#define IDEWriteSectorCount(Address, Data) (outb_p((Address) + IDE_REG_SECTOR_CNT, (Data)))
|
||||||
|
#define IDEReadSectorNum(Address) (inb_p((Address) + IDE_REG_SECTOR_NUM))
|
||||||
|
#define IDEWriteSectorNum(Address, Data) (outb_p((Address) + IDE_REG_SECTOR_NUM, (Data)))
|
||||||
|
#define IDEReadCylinderLow(Address) (inb_p((Address) + IDE_REG_CYL_LOW))
|
||||||
|
#define IDEWriteCylinderLow(Address, Data) (outb_p((Address) + IDE_REG_CYL_LOW, (Data)))
|
||||||
|
#define IDEReadCylinderHigh(Address) (inb_p((Address) + IDE_REG_CYL_HIGH))
|
||||||
|
#define IDEWriteCylinderHigh(Address, Data) (outb_p((Address) + IDE_REG_CYL_HIGH, (Data)))
|
||||||
|
#define IDEReadDriveHead(Address) (inb_p((Address) + IDE_REG_DRV_HEAD))
|
||||||
|
#define IDEWriteDriveHead(Address, Data) (outb_p((Address) + IDE_REG_DRV_HEAD, (Data)))
|
||||||
|
#define IDEReadStatus(Address) (inb_p((Address) + IDE_REG_STATUS))
|
||||||
|
#define IDEWriteCommand(Address, Data) (outb_p((Address) + IDE_REG_COMMAND, (Data)))
|
||||||
|
#define IDEReadBlock(Address, Buffer) (insw((Address) + IDE_REG_DATA_PORT, (Buffer), IDE_SECTOR_BUF_SZ / 2))
|
||||||
|
#define IDEWriteBlock(Address, Buffer) (outsw((Address) + IDE_REG_DATA_PORT, (Buffer), IDE_SECTOR_BUF_SZ / 2))
|
||||||
|
|
||||||
|
//
|
||||||
|
// Access macros for control registers
|
||||||
|
// Each macro takes an address of the control port blank and data
|
||||||
|
//
|
||||||
|
#define IDEWriteDriveControl(Address, Data) (outb_p((Address) + IDE_REG_DEV_CNTRL, (Data)))
|
||||||
|
|
||||||
|
// IDE_DEVICE_EXTENSION
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// Extension to be placed in each device object
|
||||||
|
//
|
||||||
|
// ACCESS:
|
||||||
|
// Allocated from NON-PAGED POOL
|
||||||
|
// Available at any IRQL
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef struct _IDE_DEVICE_EXTENSION {
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PCONTROLLER_OBJECT ControllerObject;
|
||||||
|
struct _IDE_DEVICE_EXTESION *DiskExtension;
|
||||||
|
int UnitNumber;
|
||||||
|
BOOLEAN LBASupported;
|
||||||
|
BOOLEAN DMASupported;
|
||||||
|
int BytesPerSector;
|
||||||
|
int LogicalHeads;
|
||||||
|
int SectorsPerLogCyl;
|
||||||
|
int SectorsPerLogTrk;
|
||||||
|
int Offset;
|
||||||
|
int Size;
|
||||||
|
|
||||||
|
int Operation;
|
||||||
|
ULONG BytesRequested;
|
||||||
|
ULONG BytesToTransfer;
|
||||||
|
ULONG BytesRemaining;
|
||||||
|
ULONG StartingSector;
|
||||||
|
int SectorsTransferred;
|
||||||
|
BYTE *TargetAddress;
|
||||||
|
|
||||||
|
} IDE_DEVICE_EXTENSION, *PIDE_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
// IDE_TIMER_STATES
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// An enumeration containing the states in the timer DFA
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef enum _IDE_TIMER_STATES {
|
||||||
|
IDETimerIdle
|
||||||
|
} IDE_TIMER_STATES;
|
||||||
|
|
||||||
|
// IDE_CONTROLLER_EXTENSION
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// Driver-defined structure used to hold miscellaneous controller information.
|
||||||
|
//
|
||||||
|
// ACCESS:
|
||||||
|
// Allocated from NON-PAGED POOL
|
||||||
|
// Available at any IRQL
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef struct _IDE_CONTROLLER_EXTENSION {
|
||||||
|
KSPIN_LOCK SpinLock;
|
||||||
|
int Number;
|
||||||
|
int Vector;
|
||||||
|
int CommandPortBase;
|
||||||
|
int ControlPortBase;
|
||||||
|
BOOLEAN DMASupported;
|
||||||
|
BOOLEAN ControllerInterruptBug;
|
||||||
|
PKINTERRUPT Interrupt;
|
||||||
|
|
||||||
|
BOOLEAN OperationInProgress;
|
||||||
|
BYTE DeviceStatus;
|
||||||
|
PIDE_DEVICE_EXTENSION DeviceForOperation;
|
||||||
|
PIRP CurrentIrp;
|
||||||
|
|
||||||
|
IDE_TIMER_STATES TimerState;
|
||||||
|
LONG TimerCount;
|
||||||
|
PDEVICE_OBJECT TimerDevice;
|
||||||
|
|
||||||
|
} IDE_CONTROLLER_EXTENSION, *PIDE_CONTROLLER_EXTENSION;
|
||||||
|
|
||||||
|
// IDE_DRIVE_IDENTIFY
|
||||||
|
|
||||||
|
typedef struct _IDE_DRIVE_IDENTIFY {
|
||||||
|
WORD ConfigBits; /*00*/
|
||||||
|
WORD LogicalCyls; /*01*/
|
||||||
|
WORD Reserved02; /*02*/
|
||||||
|
WORD LogicalHeads; /*03*/
|
||||||
|
WORD BytesPerTrack; /*04*/
|
||||||
|
WORD BytesPerSector; /*05*/
|
||||||
|
WORD SectorsPerTrack; /*06*/
|
||||||
|
BYTE InterSectorGap; /*07*/
|
||||||
|
BYTE InterSectorGapSize;
|
||||||
|
BYTE Reserved08H; /*08*/
|
||||||
|
BYTE BytesInPLO;
|
||||||
|
WORD VendorUniqueCnt; /*09*/
|
||||||
|
char SerialNumber[20]; /*10*/
|
||||||
|
WORD ControllerType; /*20*/
|
||||||
|
WORD BufferSize; /*21*/
|
||||||
|
WORD ECCByteCnt; /*22*/
|
||||||
|
char FirmwareRev[8]; /*23*/
|
||||||
|
char ModelNumber[40]; /*27*/
|
||||||
|
WORD RWMultImplemented; /*47*/
|
||||||
|
WORD DWordIOSupported; /*48*/
|
||||||
|
WORD LBADMASupported; /*49*/
|
||||||
|
WORD Reserved50; /*50*/
|
||||||
|
WORD MinPIOTransTime; /*51*/
|
||||||
|
WORD MinDMATransTime; /*52*/
|
||||||
|
WORD TMFieldsValid; /*53*/
|
||||||
|
WORD TMCylinders; /*54*/
|
||||||
|
WORD TMHeads; /*55*/
|
||||||
|
WORD TMSectorsPerTrk; /*56*/
|
||||||
|
WORD TMCapacity; /*57*/
|
||||||
|
WORD Reserved53[198]; /*58*/
|
||||||
|
} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __IDE_H */
|
||||||
|
|
||||||
|
|
20
reactos/drivers/dd/ide/idep.h
Normal file
20
reactos/drivers/dd/ide/idep.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
|
||||||
|
#define IOCTL_DISK_GET_DRIVE_GEOMETRY CTL_CODE(FILE_DEVICE_DISK, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_DISK_GET_PARTITION_INFO CTL_CODE(FILE_DEVICE_DISK, 1, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
#define IOCTL_DISK_SET_PARTITION_INFO CTL_CODE(FILE_DEVICE_DISK, 2, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||||
|
#define IOCTL_DISK_GET_DRIVE_LAYOUT CTL_CODE(FILE_DEVICE_DISK, 3, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
#define IOCTL_DISK_SET_DRIVE_LAYOUT CTL_CODE(FILE_DEVICE_DISK, 4, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||||
|
#define IOCTL_DISK_VERIFY CTL_CODE(FILE_DEVICE_DISK, 5, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_DISK_FORMAT_TRACKS CTL_CODE(FILE_DEVICE_DISK, 6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||||
|
#define IOCTL_DISK_REASSIGN_BLOCKS CTL_CODE(FILE_DEVICE_DISK, 7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||||
|
#define IOCTL_DISK_PERFORMANCE CTL_CODE(FILE_DEVICE_DISK, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_DISK_IS_WRITABLE CTL_CODE(FILE_DEVICE_DISK, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_DISK_LOGGING CTL_CODE(FILE_DEVICE_DISK, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_DISK_FORMAT_TRACKS_EX CTL_CODE(FILE_DEVICE_DISK, 11, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||||
|
#define IOCTL_DISK_HISTOGRAM_STRUCTURE CTL_CODE(FILE_DEVICE_DISK, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_DISK_HISTOGRAM_DATA CTL_CODE(FILE_DEVICE_DISK, 13, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_DISK_HISTOGRAM_RESET CTL_CODE(FILE_DEVICE_DISK, 14, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_DISK_REQUEST_STRUCTURE CTL_CODE(FILE_DEVICE_DISK, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_DISK_REQUEST_DATA CTL_CODE(FILE_DEVICE_DISK, 16, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
|
11
reactos/drivers/dd/ide/makefile
Normal file
11
reactos/drivers/dd/ide/makefile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
all: ide.o
|
||||||
|
|
||||||
|
ide.o: ide.c ide.h idep.h partitio.h
|
||||||
|
|
||||||
|
dummy:
|
||||||
|
|
||||||
|
include ../../../rules.mak
|
52
reactos/drivers/dd/ide/partitio.h
Normal file
52
reactos/drivers/dd/ide/partitio.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
*** Partition.h - defines and structs for harddrive partition info
|
||||||
|
***
|
||||||
|
*** 05/30/98 RJJ Created
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __PARTITION_H
|
||||||
|
#define __PARTITION_H
|
||||||
|
|
||||||
|
#define PARTITION_MAGIC 0xaa55
|
||||||
|
#define PART_MAGIC_OFFSET 0x01fe
|
||||||
|
#define PARTITION_OFFSET 0x01be
|
||||||
|
#define PARTITION_TBL_SIZE 4
|
||||||
|
#define PTCHSToLBA(c, h, s, scnt, hcnt) ((s) & 0x3f) + \
|
||||||
|
(scnt) * ( (h) + (hcnt) * ((c) | (((s) & 0xc0) << 2)))
|
||||||
|
#define PTLBAToCHS(lba, c, h, s, scnt, hcnt) ( \
|
||||||
|
(s) = (lba) % (scnt) + 1, \
|
||||||
|
(lba) /= (scnt), \
|
||||||
|
(h) = (lba) % (hcnt), \
|
||||||
|
(lba) /= (heads), \
|
||||||
|
(c) = (lba) & 0xff, \
|
||||||
|
(s) |= ((lba) >> 2) & 0xc0)
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum PartitionTypes {
|
||||||
|
PTEmpty = 0,
|
||||||
|
PTDOS3xPrimary = 1,
|
||||||
|
PT_OLDDOS16Bit = 4,
|
||||||
|
PTDosExtended = 5,
|
||||||
|
PTDos5xPrimary = 6
|
||||||
|
} PARTITIONTYPES;
|
||||||
|
|
||||||
|
#define PartitionIsSupported(P) ((P)->PartitionType == PTDOS3xPrimary || \
|
||||||
|
(P)->PartitionType == PT_OLDDOS16Bit || (P)->PartitionType == PTDos5xPrimary)
|
||||||
|
|
||||||
|
typedef struct Partition {
|
||||||
|
__u8 BootFlags;
|
||||||
|
__u8 StartingHead;
|
||||||
|
__u8 StartingSector;
|
||||||
|
__u8 StartingCylinder;
|
||||||
|
__u8 PartitionType;
|
||||||
|
__u8 EndingHead;
|
||||||
|
__u8 EndingSector;
|
||||||
|
__u8 EndingCylinder;
|
||||||
|
unsigned int StartingBlock;
|
||||||
|
unsigned int SectorCount;
|
||||||
|
|
||||||
|
} PARTITION;
|
||||||
|
|
||||||
|
#endif // PARTITION_H
|
||||||
|
|
||||||
|
|
710
reactos/drivers/dd/keyboard/keyboard.c
Normal file
710
reactos/drivers/dd/keyboard/keyboard.c
Normal file
|
@ -0,0 +1,710 @@
|
||||||
|
/*
|
||||||
|
** File: keyboard.c
|
||||||
|
** Description: ReactOS keyboard driver
|
||||||
|
** Current version: 0.0.4
|
||||||
|
** Last modified: 28 May 1998
|
||||||
|
**
|
||||||
|
* 31/08/98: Changed to interrupt driven model
|
||||||
|
* 29/06/98: NT interface by David Welch (welch@mcmail.com)
|
||||||
|
*
|
||||||
|
** Written by Victor Kirhenshtein (sauros@iname.com)
|
||||||
|
** Initial attempt by Jason Filby
|
||||||
|
**
|
||||||
|
** Some parts of this code are based on Linux keyboard driver
|
||||||
|
** written by Johan Myreen.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** KNOWN BUGS:
|
||||||
|
**
|
||||||
|
** * Repeat counter isn't supported
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
|
#include <internal/mmhal.h>
|
||||||
|
#include <internal/hal/io.h>
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/string.h>
|
||||||
|
#include <defines.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
#include "keyboard.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Driver data
|
||||||
|
*/
|
||||||
|
|
||||||
|
static KEY_EVENT_RECORD kbdBuffer[KBD_BUFFER_SIZE];
|
||||||
|
static int bufHead,bufTail;
|
||||||
|
static int keysInBuffer;
|
||||||
|
static int extKey;
|
||||||
|
static BYTE ledStatus;
|
||||||
|
static BYTE capsDown,numDown,scrollDown;
|
||||||
|
static DWORD ctrlKeyState;
|
||||||
|
static KSPIN_LOCK kbdBufferLock;
|
||||||
|
static PKINTERRUPT KbdInterrupt;
|
||||||
|
static KDPC KbdDpc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PURPOSE: Current irp being processed
|
||||||
|
*/
|
||||||
|
static PIRP CurrentIrp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PURPOSE: Number of keys that have been read into the current irp's buffer
|
||||||
|
*/
|
||||||
|
static ULONG KeysRead;
|
||||||
|
static ULONG KeysRequired;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Virtual key codes table
|
||||||
|
*
|
||||||
|
* Comments:
|
||||||
|
* * PrtSc = VK_PRINT
|
||||||
|
* * Alt+PrtSc (SysRq) = VK_EXECUTE
|
||||||
|
* * Alt = VK_MENU
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const WORD vkTable[128]=
|
||||||
|
{
|
||||||
|
/* 00 - 07 */ 0, VK_ESCAPE, VK_1, VK_2, VK_3, VK_4, VK_5, VK_6,
|
||||||
|
/* 08 - 0F */ VK_7, VK_8, VK_9, VK_0, 189, 187, VK_BACK, VK_TAB,
|
||||||
|
/* 10 - 17 */ VK_Q, VK_W, VK_E, VK_R, VK_T, VK_Y, VK_U, VK_I,
|
||||||
|
/* 18 - 1F */ VK_O, VK_P, 219, 221, VK_RETURN, VK_CONTROL, VK_A, VK_S,
|
||||||
|
/* 20 - 27 */ VK_D, VK_F, VK_G, VK_H, VK_J, VK_K, VK_L, 186,
|
||||||
|
/* 28 - 2F */ 222, 192, VK_SHIFT, 220, VK_Z, VK_X, VK_C, VK_V,
|
||||||
|
/* 30 - 37 */ VK_B, VK_N, VK_M, 188, 190, 191, VK_SHIFT, VK_MULTIPLY,
|
||||||
|
/* 38 - 3F */ VK_MENU, VK_SPACE, VK_CAPITAL, VK_F1, VK_F2, VK_F3, VK_F4, VK_F5,
|
||||||
|
/* 40 - 47 */ VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, VK_NUMLOCK, VK_SCROLL, VK_HOME,
|
||||||
|
/* 48 - 4F */ VK_UP, VK_PRIOR, VK_SUBTRACT, VK_LEFT, VK_CLEAR, VK_RIGHT, VK_ADD, VK_END,
|
||||||
|
/* 50 - 57 */ VK_DOWN, VK_NEXT, VK_INSERT, VK_DELETE, VK_EXECUTE, 0, 0, VK_F11,
|
||||||
|
/* 58 - 5F */ VK_F12, 0, 0, 91, 92, 93, 0, 0,
|
||||||
|
/* 60 - 67 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
/* 68 - 6F */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
/* 70 - 77 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
/* 78 - 7F */ 0, 0, 0, 0, 0, 0, 0, VK_PAUSE
|
||||||
|
};
|
||||||
|
static const WORD vkKeypadTable[13]= /* 47 - 53 */
|
||||||
|
{
|
||||||
|
VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, VK_SUBTRACT,
|
||||||
|
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_ADD,
|
||||||
|
VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD0, VK_DECIMAL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ASCII translation tables
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const BYTE asciiTable1[10]=
|
||||||
|
{
|
||||||
|
')','!','@','#','$','%','^','&','*','('
|
||||||
|
};
|
||||||
|
static const BYTE asciiTable2[16]=
|
||||||
|
{
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','*','+',0,'-','.','/'
|
||||||
|
};
|
||||||
|
static const BYTE asciiTable3[37]=
|
||||||
|
{
|
||||||
|
';','=',',','-','.','/','`', 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 const BYTE asciiTable4[37]=
|
||||||
|
{
|
||||||
|
':','+','<','_','>','?','~', 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,
|
||||||
|
'{', '|', '}', '"'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write data to keyboard
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void KbdWrite(int addr,BYTE data)
|
||||||
|
{
|
||||||
|
BYTE status;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
status=inb_p(KBD_CTRL_PORT); // Wait until input buffer empty
|
||||||
|
} while(status & KBD_IBF);
|
||||||
|
outb_p(addr,data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read data from port 0x60
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int KbdReadData(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
BYTE status,data;
|
||||||
|
|
||||||
|
i=500000;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
status=inb_p(KBD_CTRL_PORT);
|
||||||
|
if (!(status & KBD_OBF)) // Check if data available
|
||||||
|
continue;
|
||||||
|
data=inb_p(KBD_DATA_PORT);
|
||||||
|
if (status & (KBD_GTO | KBD_PERR)) // Check for timeout error
|
||||||
|
continue;
|
||||||
|
return data;
|
||||||
|
} while(--i);
|
||||||
|
return -1; // Timed out
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set keyboard LED's
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void SetKeyboardLEDs(BYTE status)
|
||||||
|
{
|
||||||
|
KbdWrite(KBD_DATA_PORT,0xED);
|
||||||
|
if (KbdReadData()!=KBD_ACK) // Error
|
||||||
|
return;
|
||||||
|
KbdWrite(KBD_DATA_PORT,status);
|
||||||
|
KbdReadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process scan code
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void ProcessScanCode(BYTE scanCode,BOOL isDown)
|
||||||
|
{
|
||||||
|
switch(scanCode)
|
||||||
|
{
|
||||||
|
case 0x1D: // Ctrl
|
||||||
|
if (extKey)
|
||||||
|
{
|
||||||
|
if (isDown)
|
||||||
|
ctrlKeyState|=RIGHT_CTRL_PRESSED;
|
||||||
|
else
|
||||||
|
ctrlKeyState&=~RIGHT_CTRL_PRESSED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isDown)
|
||||||
|
ctrlKeyState|=LEFT_CTRL_PRESSED;
|
||||||
|
else
|
||||||
|
ctrlKeyState&=~LEFT_CTRL_PRESSED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x2A: // Left shift
|
||||||
|
case 0x36: // Right shift
|
||||||
|
if (isDown)
|
||||||
|
ctrlKeyState|=SHIFT_PRESSED;
|
||||||
|
else
|
||||||
|
ctrlKeyState&=~SHIFT_PRESSED;
|
||||||
|
break;
|
||||||
|
case 0x38: // Alt
|
||||||
|
if (extKey)
|
||||||
|
{
|
||||||
|
if (isDown)
|
||||||
|
ctrlKeyState|=RIGHT_ALT_PRESSED;
|
||||||
|
else
|
||||||
|
ctrlKeyState&=~RIGHT_ALT_PRESSED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isDown)
|
||||||
|
ctrlKeyState|=LEFT_ALT_PRESSED;
|
||||||
|
else
|
||||||
|
ctrlKeyState&=~LEFT_ALT_PRESSED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x3A: // CapsLock
|
||||||
|
if (ctrlKeyState & CTRL_PRESSED)
|
||||||
|
break;
|
||||||
|
if (isDown)
|
||||||
|
{
|
||||||
|
if (!capsDown)
|
||||||
|
{
|
||||||
|
capsDown=1;
|
||||||
|
if (ctrlKeyState & CAPSLOCK_ON)
|
||||||
|
{
|
||||||
|
ledStatus&=~KBD_LED_CAPS;
|
||||||
|
ctrlKeyState&=~CAPSLOCK_ON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ledStatus|=KBD_LED_CAPS;
|
||||||
|
ctrlKeyState|=CAPSLOCK_ON;
|
||||||
|
}
|
||||||
|
SetKeyboardLEDs(ledStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
capsDown=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x45: // NumLock
|
||||||
|
if (ctrlKeyState & CTRL_PRESSED)
|
||||||
|
break;
|
||||||
|
if (isDown)
|
||||||
|
{
|
||||||
|
if (!numDown)
|
||||||
|
{
|
||||||
|
numDown=1;
|
||||||
|
if (ctrlKeyState & NUMLOCK_ON)
|
||||||
|
{
|
||||||
|
ledStatus&=~KBD_LED_NUM;
|
||||||
|
ctrlKeyState&=~NUMLOCK_ON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ledStatus|=KBD_LED_NUM;
|
||||||
|
ctrlKeyState|=NUMLOCK_ON;
|
||||||
|
}
|
||||||
|
SetKeyboardLEDs(ledStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numDown=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x46: // ScrollLock
|
||||||
|
if (ctrlKeyState & CTRL_PRESSED)
|
||||||
|
break;
|
||||||
|
if (isDown)
|
||||||
|
{
|
||||||
|
if (!scrollDown)
|
||||||
|
{
|
||||||
|
scrollDown=1;
|
||||||
|
if (ctrlKeyState & SCROLLLOCK_ON)
|
||||||
|
{
|
||||||
|
ledStatus&=~KBD_LED_SCROLL;
|
||||||
|
ctrlKeyState&=~SCROLLLOCK_ON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ledStatus|=KBD_LED_SCROLL;
|
||||||
|
ctrlKeyState|=SCROLLLOCK_ON;
|
||||||
|
}
|
||||||
|
SetKeyboardLEDs(ledStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scrollDown=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate virtual key code to ASCII
|
||||||
|
*/
|
||||||
|
|
||||||
|
static BYTE VirtualToAscii(WORD keyCode,BOOL isDown)
|
||||||
|
{
|
||||||
|
if ((ctrlKeyState & ALT_PRESSED)&&(ctrlKeyState & CTRL_PRESSED))
|
||||||
|
return 0; // Ctrl+Alt+char always 0
|
||||||
|
if ((!isDown)&&(ctrlKeyState & ALT_PRESSED))
|
||||||
|
return 0; // Alt+char is 0 when key is released
|
||||||
|
|
||||||
|
if (ctrlKeyState & CTRL_PRESSED)
|
||||||
|
{
|
||||||
|
if ((keyCode>=VK_A)&&(keyCode<=VK_Z))
|
||||||
|
return keyCode-VK_A+1;
|
||||||
|
switch(keyCode)
|
||||||
|
{
|
||||||
|
case VK_SPACE:
|
||||||
|
return ' ';
|
||||||
|
case VK_BACK:
|
||||||
|
return 127;
|
||||||
|
case VK_RETURN:
|
||||||
|
return 10;
|
||||||
|
case 219: /* [ */
|
||||||
|
if (ctrlKeyState & SHIFT_PRESSED)
|
||||||
|
return 0;
|
||||||
|
return 27;
|
||||||
|
case 220: /* \ */
|
||||||
|
if (ctrlKeyState & SHIFT_PRESSED)
|
||||||
|
return 0;
|
||||||
|
return 28;
|
||||||
|
case 221: /* ] */
|
||||||
|
if (ctrlKeyState & SHIFT_PRESSED)
|
||||||
|
return 0;
|
||||||
|
return 29;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((keyCode>=VK_A)&&(keyCode<=VK_Z))
|
||||||
|
if (ctrlKeyState & CAPSLOCK_ON)
|
||||||
|
if (ctrlKeyState & SHIFT_PRESSED)
|
||||||
|
return keyCode-VK_A+'a';
|
||||||
|
else
|
||||||
|
return keyCode-VK_A+'A';
|
||||||
|
else
|
||||||
|
if (ctrlKeyState & SHIFT_PRESSED)
|
||||||
|
return keyCode-VK_A+'A';
|
||||||
|
else
|
||||||
|
return keyCode-VK_A+'a';
|
||||||
|
|
||||||
|
if ((keyCode>=VK_0)&&(keyCode<=VK_9))
|
||||||
|
if (ctrlKeyState & SHIFT_PRESSED)
|
||||||
|
return asciiTable1[keyCode-VK_0];
|
||||||
|
else
|
||||||
|
return keyCode-VK_0+'0';
|
||||||
|
|
||||||
|
if ((keyCode>=VK_NUMPAD0)&&(keyCode<=VK_DIVIDE))
|
||||||
|
return asciiTable2[keyCode-VK_NUMPAD0];
|
||||||
|
|
||||||
|
if ((keyCode>=186)&&(keyCode<=222))
|
||||||
|
if (ctrlKeyState & SHIFT_PRESSED)
|
||||||
|
return asciiTable4[keyCode-186];
|
||||||
|
else
|
||||||
|
return asciiTable3[keyCode-186];
|
||||||
|
|
||||||
|
switch(keyCode)
|
||||||
|
{
|
||||||
|
case VK_SPACE:
|
||||||
|
return ' ';
|
||||||
|
case VK_RETURN:
|
||||||
|
return 13;
|
||||||
|
case VK_BACK:
|
||||||
|
return 8;
|
||||||
|
case VK_TAB:
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate scan code to virtual key code
|
||||||
|
*/
|
||||||
|
|
||||||
|
static WORD ScanToVirtual(BYTE scanCode)
|
||||||
|
{
|
||||||
|
if ((scanCode>=0x47)&&(scanCode<=0x53)&&(ctrlKeyState & NUMLOCK_ON)&&
|
||||||
|
(!extKey)&&(!(ctrlKeyState & SHIFT_PRESSED)))
|
||||||
|
return vkKeypadTable[scanCode-0x47];
|
||||||
|
if ((scanCode==0x35)&&(extKey)) // Gray divide
|
||||||
|
return VK_DIVIDE;
|
||||||
|
if ((scanCode==0x37)&&(extKey)) // Print screen
|
||||||
|
return VK_PRINT;
|
||||||
|
return vkTable[scanCode];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keyboard IRQ handler
|
||||||
|
*/
|
||||||
|
|
||||||
|
static VOID KbdDpcRoutine(PKDPC Dpc,
|
||||||
|
PVOID DeferredContext,
|
||||||
|
PVOID SystemArgument1,
|
||||||
|
PVOID SystemArgument2)
|
||||||
|
{
|
||||||
|
PIRP Irp = (PIRP)SystemArgument2;
|
||||||
|
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)SystemArgument1;
|
||||||
|
|
||||||
|
CHECKPOINT;
|
||||||
|
DPRINT("KbdDpcRoutine(DeviceObject %x, Irp %x)\n",
|
||||||
|
DeviceObject,Irp);
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||||
|
IoStartNextPacket(DeviceObject,FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int KeyboardHandler(unsigned int irq)
|
||||||
|
{
|
||||||
|
BYTE resp,thisKey;
|
||||||
|
BOOL isDown;
|
||||||
|
static BYTE lastKey;
|
||||||
|
|
||||||
|
CHECKPOINT;
|
||||||
|
|
||||||
|
// Read scan code
|
||||||
|
thisKey=inb_p(KBD_DATA_PORT);
|
||||||
|
if ((thisKey==0xE0)||(thisKey==0xE1)) // Extended key
|
||||||
|
{
|
||||||
|
extKey=1; // Wait for next byte
|
||||||
|
lastKey=thisKey;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
isDown=!(thisKey & 0x80);
|
||||||
|
thisKey&=0x7F;
|
||||||
|
|
||||||
|
// The keyboard maintains its own internal caps lock and num lock
|
||||||
|
// statuses. In caps lock mode E0 AA precedes make code and
|
||||||
|
// E0 2A follow break code. In num lock mode, E0 2A precedes
|
||||||
|
// make code and E0 AA follow break code. We maintain our own caps lock
|
||||||
|
// and num lock statuses, so we will just ignore these.
|
||||||
|
// Some keyboards have L-Shift/R-Shift modes instead of caps lock
|
||||||
|
// mode. If right shift pressed, E0 B6 / E0 36 pairs generated.
|
||||||
|
if (extKey & ((thisKey==0x2A)||(thisKey==0x36)))
|
||||||
|
{
|
||||||
|
extKey=0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for PAUSE sequence
|
||||||
|
if (extKey && (lastKey==0xE1))
|
||||||
|
{
|
||||||
|
if (thisKey==0x1D)
|
||||||
|
lastKey=0xFF; // Sequence is OK
|
||||||
|
else
|
||||||
|
extKey=0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (extKey && (lastKey==0xFF))
|
||||||
|
{
|
||||||
|
if (thisKey!=0x45)
|
||||||
|
{
|
||||||
|
extKey=0; // Bad sequence
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
thisKey=0x7F; // Pseudo-code for PAUSE
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessScanCode(thisKey,isDown);
|
||||||
|
|
||||||
|
DPRINT("Key: '%c'\n",VirtualToAscii(ScanToVirtual(thisKey),isDown));
|
||||||
|
|
||||||
|
if (CurrentIrp!=NULL)
|
||||||
|
{
|
||||||
|
KEY_EVENT_RECORD* rec = (KEY_EVENT_RECORD *)
|
||||||
|
CurrentIrp->AssociatedIrp.SystemBuffer;
|
||||||
|
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(CurrentIrp);
|
||||||
|
|
||||||
|
CHECKPOINT;
|
||||||
|
|
||||||
|
rec[KeysRead].bKeyDown=isDown;
|
||||||
|
rec[KeysRead].wRepeatCount=1;
|
||||||
|
rec[KeysRead].wVirtualKeyCode=ScanToVirtual(thisKey);
|
||||||
|
rec[KeysRead].wVirtualScanCode=thisKey;
|
||||||
|
rec[KeysRead].AsciiChar=VirtualToAscii(rec->wVirtualKeyCode,isDown);
|
||||||
|
rec[KeysRead].dwControlKeyState=ctrlKeyState;
|
||||||
|
if (extKey)
|
||||||
|
{
|
||||||
|
rec[KeysRead].dwControlKeyState|=ENHANCED_KEY;
|
||||||
|
}
|
||||||
|
KeysRead++;
|
||||||
|
DPRINT("KeysRequired %d KeysRead %x\n",KeysRequired,KeysRead);
|
||||||
|
if (KeysRead==KeysRequired)
|
||||||
|
{
|
||||||
|
KeInsertQueueDpc(&KbdDpc,stk->DeviceObject,CurrentIrp);
|
||||||
|
CurrentIrp=NULL;
|
||||||
|
}
|
||||||
|
CHECKPOINT;
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer is full ?
|
||||||
|
if (keysInBuffer==KBD_BUFFER_SIZE) // Buffer is full
|
||||||
|
{
|
||||||
|
extKey=0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
kbdBuffer[bufHead].bKeyDown=isDown;
|
||||||
|
kbdBuffer[bufHead].wRepeatCount=1;
|
||||||
|
kbdBuffer[bufHead].wVirtualKeyCode=ScanToVirtual(thisKey);
|
||||||
|
kbdBuffer[bufHead].wVirtualScanCode=thisKey;
|
||||||
|
// kbdBuffer[bufHead].uChar.AsciiChar=TranslateScanCode(thisKey);
|
||||||
|
kbdBuffer[bufHead].AsciiChar=VirtualToAscii(kbdBuffer[bufHead].wVirtualKeyCode,isDown);
|
||||||
|
kbdBuffer[bufHead].dwControlKeyState=ctrlKeyState;
|
||||||
|
if (extKey)
|
||||||
|
kbdBuffer[bufHead].dwControlKeyState|=ENHANCED_KEY;
|
||||||
|
bufHead++;
|
||||||
|
bufHead&=KBD_WRAP_MASK; // Modulo KBD_BUFFER_SIZE
|
||||||
|
keysInBuffer++;
|
||||||
|
extKey=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize keyboard
|
||||||
|
//
|
||||||
|
static void KeyboardConnectInterrupt(void)
|
||||||
|
{
|
||||||
|
ULONG MappedIrq;
|
||||||
|
KIRQL Dirql;
|
||||||
|
KAFFINITY Affinity;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
MappedIrq = HalGetInterruptVector(Internal,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
KEYBOARD_IRQ,
|
||||||
|
&Dirql,
|
||||||
|
&Affinity);
|
||||||
|
Status = IoConnectInterrupt(&KbdInterrupt,
|
||||||
|
KeyboardHandler,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
MappedIrq,
|
||||||
|
Dirql,
|
||||||
|
Dirql,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
Affinity,
|
||||||
|
FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int InitializeKeyboard(void)
|
||||||
|
{
|
||||||
|
// Initialize variables
|
||||||
|
bufHead=0;
|
||||||
|
bufTail=0;
|
||||||
|
keysInBuffer=0;
|
||||||
|
ledStatus=0;
|
||||||
|
capsDown=0;
|
||||||
|
numDown=0;
|
||||||
|
scrollDown=0;
|
||||||
|
ctrlKeyState=0;
|
||||||
|
extKey=0;
|
||||||
|
|
||||||
|
KeyboardConnectInterrupt();
|
||||||
|
KeInitializeDpc(&KbdDpc,KbdDpcRoutine,NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read data from keyboard buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void dummy(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN KbdSynchronizeRoutine(PVOID Context)
|
||||||
|
{
|
||||||
|
PIRP Irp = (PIRP)Context;
|
||||||
|
KEY_EVENT_RECORD* rec = (KEY_EVENT_RECORD *)
|
||||||
|
Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
ULONG NrToRead = stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DPRINT("NrToRead %d keysInBuffer %d\n",NrToRead,keysInBuffer);
|
||||||
|
NrToRead = min(NrToRead,keysInBuffer);
|
||||||
|
|
||||||
|
DPRINT("NrToRead %d stk->Parameters.Read.Length %d\n",
|
||||||
|
NrToRead,stk->Parameters.Read.Length);
|
||||||
|
DPRINT("sizeof(KEY_EVENT_RECORD) %d\n",sizeof(KEY_EVENT_RECORD));
|
||||||
|
for (i=0;i<NrToRead;i++)
|
||||||
|
{
|
||||||
|
memcpy(&rec[i],&kbdBuffer[bufTail],sizeof(KEY_EVENT_RECORD));
|
||||||
|
bufTail++;
|
||||||
|
bufTail&=KBD_WRAP_MASK;
|
||||||
|
keysInBuffer--;
|
||||||
|
}
|
||||||
|
if ((stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD))==NrToRead)
|
||||||
|
{
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeysRequired=stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD);
|
||||||
|
KeysRead=NrToRead;
|
||||||
|
CurrentIrp=Irp;
|
||||||
|
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID KbdStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
DPRINT("KeyboardStartIo(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||||
|
|
||||||
|
DPRINT("stk->Parameters.Read.Length %d\n",stk->Parameters.Read.Length);
|
||||||
|
DPRINT("KeysRequired %d\n",KeysRequired);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("DeviceObject %x\n",DeviceObject);
|
||||||
|
DPRINT("Irp %x\n",Irp);
|
||||||
|
|
||||||
|
switch (stk->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_CREATE:
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_READ:
|
||||||
|
DPRINT("Handling Read request\n");
|
||||||
|
if (KeSynchronizeExecution(KbdInterrupt,KbdSynchronizeRoutine,Irp))
|
||||||
|
{
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Queueing packet\n");
|
||||||
|
IoStartPacket(DeviceObject,Irp,NULL,NULL);
|
||||||
|
Status = STATUS_PENDING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status==STATUS_PENDING)
|
||||||
|
{
|
||||||
|
DPRINT("Marking irp pending\n");
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
DbgPrint("Keyboard Driver 0.0.4\n");
|
||||||
|
InitializeKeyboard();
|
||||||
|
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdDispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdDispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_READ] = KbdDispatch;
|
||||||
|
DriverObject->DriverStartIo = KbdStartIo;
|
||||||
|
|
||||||
|
RtlInitAnsiString(&adevice_name,"\\Device\\Keyboard");
|
||||||
|
RtlAnsiStringToUnicodeString(&device_name,&adevice_name,TRUE);
|
||||||
|
IoCreateDevice(DriverObject,0,&device_name,FILE_DEVICE_KEYBOARD,0,
|
||||||
|
TRUE,&DeviceObject);
|
||||||
|
DeviceObject->Flags = DO_BUFFERED_IO;
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
67
reactos/drivers/dd/keyboard/keyboard.h
Normal file
67
reactos/drivers/dd/keyboard/keyboard.h
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Some defines
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KEYBOARD_IRQ 1
|
||||||
|
#define KBD_BUFFER_SIZE 32
|
||||||
|
#define KBD_WRAP_MASK 0x1F
|
||||||
|
|
||||||
|
#define disable() __asm__("cli\n\t")
|
||||||
|
#define enable() __asm__("sti\n\t")
|
||||||
|
|
||||||
|
#define ALT_PRESSED (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)
|
||||||
|
#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keyboard controller ports
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KBD_DATA_PORT 0x60
|
||||||
|
#define KBD_CTRL_PORT 0x64
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Controller commands
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KBD_READ_MODE 0x20
|
||||||
|
#define KBD_WRITE_MODE 0x60
|
||||||
|
#define KBD_SELF_TEST 0xAA
|
||||||
|
#define KBD_LINE_TEST 0xAB
|
||||||
|
#define KBD_CTRL_ENABLE 0xAE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keyboard commands
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KBD_ENABLE 0xF4
|
||||||
|
#define KBD_DISABLE 0xF5
|
||||||
|
#define KBD_RESET 0xFF
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keyboard responces
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KBD_ACK 0xFA
|
||||||
|
#define KBD_BATCC 0xAA
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Controller status register bits
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KBD_OBF 0x01
|
||||||
|
#define KBD_IBF 0x02
|
||||||
|
#define KBD_GTO 0x40
|
||||||
|
#define KBD_PERR 0x80
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LED bits
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KBD_LED_SCROLL 0x01
|
||||||
|
#define KBD_LED_NUM 0x02
|
||||||
|
#define KBD_LED_CAPS 0x04
|
1
reactos/drivers/dd/keyboard/makefile
Normal file
1
reactos/drivers/dd/keyboard/makefile
Normal file
|
@ -0,0 +1 @@
|
||||||
|
all: keyboard.o
|
1
reactos/drivers/dd/mouse/makefile
Normal file
1
reactos/drivers/dd/mouse/makefile
Normal file
|
@ -0,0 +1 @@
|
||||||
|
all: mouse.o
|
268
reactos/drivers/dd/mouse/mouse.c
Normal file
268
reactos/drivers/dd/mouse/mouse.c
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
** Mouse driver 0.0.3
|
||||||
|
** Written by Jason Filby (jasonfilby@yahoo.com)
|
||||||
|
** For ReactOS (www.sid-dis.com/reactos)
|
||||||
|
|
||||||
|
** Note: The serial.o driver must be loaded before loading this driver
|
||||||
|
|
||||||
|
** Known Limitations:
|
||||||
|
** Only supports mice on COM port 1
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <internal/mmhal.h>
|
||||||
|
#include <internal/hal/io.h>
|
||||||
|
#include <internal/hal/ddk.h>
|
||||||
|
#include <funcs.h>
|
||||||
|
|
||||||
|
#define MOUSE_IRQ_COM1 4
|
||||||
|
#define MOUSE_IRQ_COM2 3
|
||||||
|
|
||||||
|
#define COM1_PORT 0x3f8
|
||||||
|
#define COM2_PORT 0x2f8
|
||||||
|
|
||||||
|
#define max_screen_x 79
|
||||||
|
#define max_screen_y 24
|
||||||
|
|
||||||
|
static unsigned int MOUSE_IRQ=MOUSE_IRQ_COM1;
|
||||||
|
static unsigned int MOUSE_COM=COM1_PORT;
|
||||||
|
|
||||||
|
static unsigned int bytepos=0, coordinate;
|
||||||
|
static unsigned char mpacket[3];
|
||||||
|
static signed int mouse_x=40, mouse_y=12;
|
||||||
|
static unsigned char mouse_button1, mouse_button2;
|
||||||
|
static signed int horiz_sensitivity, vert_sensitivity;
|
||||||
|
|
||||||
|
BOOLEAN microsoft_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext)
|
||||||
|
{
|
||||||
|
unsigned int mbyte=inb(MOUSE_COM);
|
||||||
|
|
||||||
|
// Synchronize
|
||||||
|
if((mbyte&64)==64) { bytepos=0; };
|
||||||
|
|
||||||
|
mpacket[bytepos]=mbyte;
|
||||||
|
bytepos++;
|
||||||
|
|
||||||
|
// Process packet
|
||||||
|
if(bytepos==3) {
|
||||||
|
// Retrieve change in x and y from packet
|
||||||
|
int change_x=((mpacket[0] & 3) << 6) + mpacket[1];
|
||||||
|
int change_y=((mpacket[0] & 12) << 4) + mpacket[2];
|
||||||
|
|
||||||
|
// Some mice need this
|
||||||
|
if(coordinate==1) {
|
||||||
|
change_x-=128;
|
||||||
|
change_y-=128;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Change to signed
|
||||||
|
if(change_x>=128) { change_x=change_x-256; };
|
||||||
|
if(change_y>=128) { change_y=change_y-256; };
|
||||||
|
|
||||||
|
// Adjust mouse position according to sensitivity
|
||||||
|
mouse_x+=change_x/horiz_sensitivity;
|
||||||
|
mouse_y+=change_y/vert_sensitivity;
|
||||||
|
|
||||||
|
// Check that mouse is still in screen
|
||||||
|
if(mouse_x<0) { mouse_x=0; };
|
||||||
|
if(mouse_x>max_screen_x) { mouse_x=max_screen_x; };
|
||||||
|
if(mouse_y<0) { mouse_y=0; };
|
||||||
|
if(mouse_y>max_screen_y) { mouse_y=max_screen_y; };
|
||||||
|
|
||||||
|
// Retrieve mouse button status from packet
|
||||||
|
mouse_button1=mpacket[0] & 32;
|
||||||
|
mouse_button2=mpacket[0] & 16;
|
||||||
|
|
||||||
|
bytepos=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void InitializeMouseHardware(unsigned int mtype)
|
||||||
|
{
|
||||||
|
char clear_error_bits;
|
||||||
|
|
||||||
|
outb_p(MOUSE_COM+3, 0x80); // set DLAB on
|
||||||
|
outb_p(MOUSE_COM, 0x60); // speed LO byte
|
||||||
|
outb_p(MOUSE_COM+1, 0); // speed HI byte
|
||||||
|
outb_p(MOUSE_COM+3, mtype); // 2=MS Mouse; 3=Mouse systems mouse
|
||||||
|
outb_p(MOUSE_COM+1, 0); // set comm and DLAB to 0
|
||||||
|
outb_p(MOUSE_COM+4, 1); // DR int enable
|
||||||
|
|
||||||
|
clear_error_bits=inb_p(MOUSE_COM+5); // clear error bits
|
||||||
|
};
|
||||||
|
|
||||||
|
int DetMicrosoft(void)
|
||||||
|
{
|
||||||
|
char tmp, ind;
|
||||||
|
int buttons=0, i;
|
||||||
|
|
||||||
|
outb_p(MOUSE_COM+4, 0x0b);
|
||||||
|
tmp=inb_p(MOUSE_COM);
|
||||||
|
|
||||||
|
// Check the first for bytes for signs that this is an MS mouse
|
||||||
|
for(i=0; i<4; i++) {
|
||||||
|
while((inb_p(MOUSE_COM+5) & 1)==0) ;
|
||||||
|
ind=inb_p(MOUSE_COM);
|
||||||
|
if(ind==0x33) buttons=3;
|
||||||
|
if(ind==0x4d) buttons=2;
|
||||||
|
};
|
||||||
|
|
||||||
|
return buttons;
|
||||||
|
};
|
||||||
|
|
||||||
|
int CheckMouseType(unsigned int mtype)
|
||||||
|
{
|
||||||
|
unsigned int retval=0;
|
||||||
|
|
||||||
|
InitializeMouseHardware(mtype);
|
||||||
|
if(mtype==2) retval=DetMicrosoft();
|
||||||
|
if(mtype==3) {
|
||||||
|
outb_p(MOUSE_COM+4, 11);
|
||||||
|
retval=3;
|
||||||
|
};
|
||||||
|
outb_p(MOUSE_COM+1, 1);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ClearMouse(void)
|
||||||
|
{
|
||||||
|
// Waits until the mouse calms down but also quits out after a while
|
||||||
|
// in case some destructive user wants to keep moving the mouse
|
||||||
|
// before we're done
|
||||||
|
|
||||||
|
unsigned int restarts=0, i;
|
||||||
|
for (i=0; i<60000; i++)
|
||||||
|
{
|
||||||
|
unsigned temp=inb(MOUSE_COM);
|
||||||
|
if(temp!=0) {
|
||||||
|
restarts++;
|
||||||
|
if(restarts<300000) {
|
||||||
|
i=0;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
i=60000;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
void InitializeMouse(void)
|
||||||
|
{
|
||||||
|
int mbuttons=0, gotmouse=0;
|
||||||
|
ULONG MappedIrq;
|
||||||
|
KIRQL Dirql;
|
||||||
|
KAFFINITY Affinity;
|
||||||
|
PKINTERRUPT IrqObject;
|
||||||
|
|
||||||
|
horiz_sensitivity=2;
|
||||||
|
vert_sensitivity=3;
|
||||||
|
|
||||||
|
// Check for Microsoft mouse (2 buttons)
|
||||||
|
if(CheckMouseType(2)!=0)
|
||||||
|
{
|
||||||
|
gotmouse=1;
|
||||||
|
DbgPrint("Microsoft Mouse Detected\n");
|
||||||
|
ClearMouse();
|
||||||
|
coordinate=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check for Microsoft Systems mouse (3 buttons)
|
||||||
|
if(gotmouse==0) {
|
||||||
|
if(CheckMouseType(3)!=0)
|
||||||
|
{
|
||||||
|
gotmouse=1;
|
||||||
|
DbgPrint("Microsoft Mouse Detected\n");
|
||||||
|
ClearMouse();
|
||||||
|
coordinate=1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if(gotmouse==0) {
|
||||||
|
DbgPrint("No Mouse Detected!\n");
|
||||||
|
} else {
|
||||||
|
MappedIrq = HalGetInterruptVector(Internal, 0, 0, MOUSE_IRQ,
|
||||||
|
&Dirql, &Affinity);
|
||||||
|
|
||||||
|
IoConnectInterrupt(&IrqObject, microsoft_mouse_handler, NULL,
|
||||||
|
NULL, MappedIrq, Dirql, Dirql, 0, FALSE,
|
||||||
|
Affinity, FALSE);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// For test purposes only
|
||||||
|
unsigned char get_text_char(int x, int y)
|
||||||
|
{
|
||||||
|
unsigned char getchar;
|
||||||
|
char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2)));
|
||||||
|
getchar=*vidmem;
|
||||||
|
return getchar;
|
||||||
|
};
|
||||||
|
|
||||||
|
// For test purposes only
|
||||||
|
unsigned char get_text_color(int x, int y)
|
||||||
|
{
|
||||||
|
unsigned char getcolor;
|
||||||
|
char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2)));
|
||||||
|
vidmem++;
|
||||||
|
getcolor=*vidmem;
|
||||||
|
return getcolor;
|
||||||
|
};
|
||||||
|
|
||||||
|
// For test purposes only
|
||||||
|
void put_text_char(int x, int y, unsigned char putchar[2])
|
||||||
|
{
|
||||||
|
char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2)));
|
||||||
|
*vidmem=putchar[0];
|
||||||
|
vidmem++;
|
||||||
|
*vidmem=putchar[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
// For test purposes only
|
||||||
|
void test_mouse(void)
|
||||||
|
{
|
||||||
|
static int i=0, forcechange=0;
|
||||||
|
static int old_x=40, old_y=12;
|
||||||
|
static unsigned char old_cursor[2], new_cursor[2];
|
||||||
|
|
||||||
|
DbgPrint("Testing mouse...");
|
||||||
|
|
||||||
|
old_cursor[0]=' ';
|
||||||
|
old_cursor[1]=7;
|
||||||
|
new_cursor[0]='Û';
|
||||||
|
new_cursor[1]=15;
|
||||||
|
|
||||||
|
old_cursor[0]=get_text_char(mouse_x, mouse_y);
|
||||||
|
old_cursor[1]=get_text_color(mouse_x, mouse_y);
|
||||||
|
put_text_char(mouse_x, mouse_y, new_cursor);
|
||||||
|
|
||||||
|
while(i!=1)
|
||||||
|
{
|
||||||
|
if(mouse_button1!=0) { new_cursor[1]=10; mouse_button1=0; forcechange=1; };
|
||||||
|
if(mouse_button2!=0) { new_cursor[1]=12; mouse_button2=0; forcechange=1; };
|
||||||
|
|
||||||
|
if((mouse_x!=old_x) || (mouse_y!=old_y) || (forcechange==1)) {
|
||||||
|
forcechange=0;
|
||||||
|
|
||||||
|
put_text_char(old_x, old_y, old_cursor);
|
||||||
|
old_cursor[0]=get_text_char(mouse_x, mouse_y);
|
||||||
|
old_cursor[1]=get_text_color(mouse_x, mouse_y);
|
||||||
|
put_text_char(mouse_x, mouse_y, new_cursor);
|
||||||
|
|
||||||
|
old_x=mouse_x;
|
||||||
|
old_y=mouse_y;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
|
{
|
||||||
|
DbgPrint("Mouse Driver 0.0.3\n");
|
||||||
|
InitializeMouse();
|
||||||
|
test_mouse();
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
};
|
||||||
|
|
1
reactos/drivers/dd/null/makefile
Normal file
1
reactos/drivers/dd/null/makefile
Normal file
|
@ -0,0 +1 @@
|
||||||
|
all: null.o
|
104
reactos/drivers/dd/null/null.c
Normal file
104
reactos/drivers/dd/null/null.c
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/null/null.c
|
||||||
|
* PURPOSE: NULL device driver
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* 13/08/98: Created
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
|
||||||
|
/* FUNCTIONS **************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS NullWrite(PIRP Irp, PIO_STACK_LOCATION stk)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = stk->Parameters.Write.Length;
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NullRead(PIRP Irp, PIO_STACK_LOCATION stk)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
return(STATUS_END_OF_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NullDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Handles user mode requests
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DeviceObject = Device for request
|
||||||
|
* Irp = I/O request packet describing request
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
switch (Stack->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_CREATE:
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_WRITE:
|
||||||
|
status = NullWrite(Irp,Stack);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_READ:
|
||||||
|
status = NullRead(Irp,Stack);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = status;
|
||||||
|
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||||
|
return(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NullUnload(PDRIVER_OBJECT DriverObject)
|
||||||
|
{
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Called by the system to initalize the driver
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DriverObject = object describing this driver
|
||||||
|
* RegistryPath = path to our configuration entries
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
NTSTATUS ret;
|
||||||
|
ANSI_STRING ansi_device_name;
|
||||||
|
UNICODE_STRING device_name;
|
||||||
|
|
||||||
|
DbgPrint("Null Device Driver 0.0.1\n");
|
||||||
|
|
||||||
|
RtlInitAnsiString(&ansi_device_name,"\\Device\\NUL");
|
||||||
|
RtlAnsiStringToUnicodeString(&device_name,&ansi_device_name,TRUE);
|
||||||
|
ret = IoCreateDevice(DriverObject,0,&device_name,
|
||||||
|
FILE_DEVICE_NULL,0,FALSE,&DeviceObject);
|
||||||
|
if (ret!=STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceObject->Flags=0;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = NullDispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = NullDispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = NullDispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_READ] = NullDispatch;
|
||||||
|
DriverObject->DriverUnload = NullUnload;
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
1
reactos/drivers/dd/parallel/makefile
Normal file
1
reactos/drivers/dd/parallel/makefile
Normal file
|
@ -0,0 +1 @@
|
||||||
|
all: parallel.o
|
144
reactos/drivers/dd/parallel/parallel.c
Normal file
144
reactos/drivers/dd/parallel/parallel.c
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/parallel/parallel.c
|
||||||
|
* PURPOSE: Parallel port driver
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* ??/??/??: Created
|
||||||
|
* 18/06/98: Made more NT like
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FUNCTIONS **************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
|
||||||
|
#include "parallel.h"
|
||||||
|
|
||||||
|
#define LP_B (0x378)
|
||||||
|
#define LP_S (inb_p(LP_B+1))
|
||||||
|
#define LP_C (LP_B+2)
|
||||||
|
|
||||||
|
static void Parallel_Reset(void)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Resets the device attached to the parallel port
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
outb_p(LP_C,0);
|
||||||
|
for (i=0;i<LP_DELAY;i++);
|
||||||
|
outb_p(LP_C,LP_PSELECP | LP_PINITP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Parallel_putchar(unsigned char ch)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Writes a character to the parallel port
|
||||||
|
* ARGUMENTS:
|
||||||
|
* ch = character to write
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
|
||||||
|
int count=0;
|
||||||
|
int status;
|
||||||
|
int wait=0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
status=LP_S;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
while ( count < 500000 && !(status & LP_PBUSY) );
|
||||||
|
|
||||||
|
if (count==500000)
|
||||||
|
{
|
||||||
|
printk("printer_putchar(): timed out\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
outb_p(LP_B,ch);
|
||||||
|
while (wait != 10000) { wait++; }
|
||||||
|
outb_p(LP_C, (LP_PSELECP | LP_PINITP | LP_PSTROBE ));
|
||||||
|
while (wait) { wait--; }
|
||||||
|
outb_p(LP_C, LP_PSELECP | LP_PINITP);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Handles user mode requests
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DeviceObject = Device for request
|
||||||
|
* Irp = I/O request packet describing request
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
NTSTATUS status;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch (Stack->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_CREATE:
|
||||||
|
printk("(Parallel Port Driver) Creating\n");
|
||||||
|
Parallel_Reset();
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_WRITE:
|
||||||
|
printk("(Parallel Port Driver) Writing %d bytes\n",
|
||||||
|
Stack->Parameters.Write.Length);
|
||||||
|
for (i=0;i<Stack->Parameters.Write.Length;i++)
|
||||||
|
{
|
||||||
|
Parallel_putchar(((char *)Irp->UserBuffer)[i]);
|
||||||
|
}
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Called by the system to initalize the driver
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DriverObject = object describing this driver
|
||||||
|
* RegistryPath = path to our configuration entries
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
NTSTATUS ret;
|
||||||
|
|
||||||
|
printk("Parallel Port Driver 0.0.1\n");
|
||||||
|
|
||||||
|
|
||||||
|
ret = IoCreateDevice(DriverObject,0,"\\Device\\Parallel",
|
||||||
|
FILE_DEVICE_PARALLEL_PORT,0,FALSE,&DeviceObject);
|
||||||
|
if (ret!=STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceObject->Flags=0;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
|
||||||
|
DriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
137
reactos/drivers/dd/parallel/parallel.h
Normal file
137
reactos/drivers/dd/parallel/parallel.h
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
#ifndef _LINUX_LP_H
|
||||||
|
#define _LINUX_LP_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* usr/include/linux/lp.h c.1991-1992 James Wiegand
|
||||||
|
* many modifications copyright (C) 1992 Michael K. Johnson
|
||||||
|
* Interrupt support added 1993 Nigel Gamble
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Per POSIX guidelines, this module reserves the LP and lp prefixes
|
||||||
|
* These are the lp_table[minor].flags flags...
|
||||||
|
*/
|
||||||
|
#define LP_EXIST 0x0001
|
||||||
|
#define LP_SELEC 0x0002
|
||||||
|
#define LP_BUSY 0x0004
|
||||||
|
#define LP_OFFL 0x0008
|
||||||
|
#define LP_NOPA 0x0010
|
||||||
|
#define LP_ERR 0x0020
|
||||||
|
#define LP_ABORT 0x0040
|
||||||
|
#define LP_CAREFUL 0x0080
|
||||||
|
#define LP_ABORTOPEN 0x0100
|
||||||
|
|
||||||
|
/* timeout for each character. This is relative to bus cycles -- it
|
||||||
|
* is the count in a busy loop. THIS IS THE VALUE TO CHANGE if you
|
||||||
|
* have extremely slow printing, or if the machine seems to slow down
|
||||||
|
* a lot when you print. If you have slow printing, increase this
|
||||||
|
* number and recompile, and if your system gets bogged down, decrease
|
||||||
|
* this number. This can be changed with the tunelp(8) command as well.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LP_INIT_CHAR 1000
|
||||||
|
|
||||||
|
/* The parallel port specs apparently say that there needs to be
|
||||||
|
* a .5usec wait before and after the strobe. Since there are wildly
|
||||||
|
* different computers running linux, I can't come up with a perfect
|
||||||
|
* value, but since it worked well on most printers before without,
|
||||||
|
* I'll initialize it to 0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LP_INIT_WAIT 0
|
||||||
|
|
||||||
|
/* This is the amount of time that the driver waits for the printer to
|
||||||
|
* catch up when the printer's buffer appears to be filled. If you
|
||||||
|
* want to tune this and have a fast printer (i.e. HPIIIP), decrease
|
||||||
|
* this number, and if you have a slow printer, increase this number.
|
||||||
|
* This is in hundredths of a second, the default 2 being .05 second.
|
||||||
|
* Or use the tunelp(8) command, which is especially nice if you want
|
||||||
|
* change back and forth between character and graphics printing, which
|
||||||
|
* are wildly different...
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LP_INIT_TIME 2
|
||||||
|
|
||||||
|
/* IOCTL numbers */
|
||||||
|
#define LPCHAR 0x0601 /* corresponds to LP_INIT_CHAR */
|
||||||
|
#define LPTIME 0x0602 /* corresponds to LP_INIT_TIME */
|
||||||
|
#define LPABORT 0x0604 /* call with TRUE arg to abort on error,
|
||||||
|
FALSE to retry. Default is retry. */
|
||||||
|
#define LPSETIRQ 0x0605 /* call with new IRQ number,
|
||||||
|
or 0 for polling (no IRQ) */
|
||||||
|
#define LPGETIRQ 0x0606 /* get the current IRQ number */
|
||||||
|
#define LPWAIT 0x0608 /* corresponds to LP_INIT_WAIT */
|
||||||
|
#define LPCAREFUL 0x0609 /* call with TRUE arg to require out-of-paper, off-
|
||||||
|
line, and error indicators good on all writes,
|
||||||
|
FALSE to ignore them. Default is ignore. */
|
||||||
|
#define LPABORTOPEN 0x060a /* call with TRUE arg to abort open() on error,
|
||||||
|
FALSE to ignore error. Default is ignore. */
|
||||||
|
#define LPGETSTATUS 0x060b /* return LP_S(minor) */
|
||||||
|
#define LPRESET 0x060c /* reset printer */
|
||||||
|
|
||||||
|
/* timeout for printk'ing a timeout, in jiffies (100ths of a second).
|
||||||
|
This is also used for re-checking error conditions if LP_ABORT is
|
||||||
|
not set. This is the default behavior. */
|
||||||
|
|
||||||
|
#define LP_TIMEOUT_INTERRUPT (60 * HZ)
|
||||||
|
#define LP_TIMEOUT_POLLED (10 * HZ)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define LP_B(minor) lp_table[(minor)].base /* IO address */
|
||||||
|
#define LP_F(minor) lp_table[(minor)].flags /* flags for busy, etc. */
|
||||||
|
#define LP_S(minor) inb_p(LP_B((minor)) + 1) /* status port */
|
||||||
|
#define LP_C(minor) (lp_table[(minor)].base + 2) /* control port */
|
||||||
|
#define LP_CHAR(minor) lp_table[(minor)].chars /* busy timeout */
|
||||||
|
#define LP_TIME(minor) lp_table[(minor)].time /* wait time */
|
||||||
|
#define LP_WAIT(minor) lp_table[(minor)].wait /* strobe wait */
|
||||||
|
#define LP_IRQ(minor) lp_table[(minor)].irq /* interrupt # */
|
||||||
|
/* 0 means polled */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LP_BUFFER_SIZE 256
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following constants describe the various signals of the printer port
|
||||||
|
* hardware. Note that the hardware inverts some signals and that some
|
||||||
|
* signals are active low. An example is LP_STROBE, which must be programmed
|
||||||
|
* with 1 for being active and 0 for being inactive, because the strobe signal
|
||||||
|
* gets inverted, but it is also active low.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bit defines for 8255 status port
|
||||||
|
* base + 1
|
||||||
|
* accessed with LP_S(minor), which gets the byte...
|
||||||
|
*/
|
||||||
|
#define LP_PBUSY 0x80 /* inverted input, active high */
|
||||||
|
#define LP_PACK 0x40 /* unchanged input, active low */
|
||||||
|
#define LP_POUTPA 0x20 /* unchanged input, active high */
|
||||||
|
#define LP_PSELECD 0x10 /* unchanged input, active high */
|
||||||
|
#define LP_PERRORP 0x08 /* unchanged input, active low */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* defines for 8255 control port
|
||||||
|
* base + 2
|
||||||
|
* accessed with LP_C(minor)
|
||||||
|
*/
|
||||||
|
#define LP_PINTEN 0x10
|
||||||
|
#define LP_PSELECP 0x08 /* inverted output, active low */
|
||||||
|
#define LP_PINITP 0x04 /* unchanged output, active low */
|
||||||
|
#define LP_PAUTOLF 0x02 /* inverted output, active low */
|
||||||
|
#define LP_PSTROBE 0x01 /* inverted output, active low */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the value written to ports to test existence. PC-style ports will
|
||||||
|
* return the value written. AT-style ports will return 0. so why not
|
||||||
|
* make them the same ?
|
||||||
|
*/
|
||||||
|
#define LP_DUMMY 0x00
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the port delay time. Your mileage may vary.
|
||||||
|
* It is used only in the lp_init() routine.
|
||||||
|
*/
|
||||||
|
#define LP_DELAY 150000
|
||||||
|
|
||||||
|
#endif
|
4
reactos/drivers/dd/sdisk/makefile
Normal file
4
reactos/drivers/dd/sdisk/makefile
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
all: sdisk.o
|
||||||
|
|
||||||
|
WIN32_LEAN_AND_MEAN = yes
|
||||||
|
include ../../../rules.mak
|
162
reactos/drivers/dd/sdisk/sdisk.c
Normal file
162
reactos/drivers/dd/sdisk/sdisk.c
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/sdisk/sdisk.c
|
||||||
|
* PURPOSE: Disk driver for Bochs
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/hal/io.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
/* FUNCTIONS **************************************************************/
|
||||||
|
|
||||||
|
#define PORT (0x3ec)
|
||||||
|
|
||||||
|
static VOID SdWriteOffset(ULONG Offset)
|
||||||
|
{
|
||||||
|
outl_p(PORT,Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Handles user mode requests
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DeviceObject = Device for request
|
||||||
|
* Irp = I/O request packet describing request
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
NTSTATUS status;
|
||||||
|
int i;
|
||||||
|
PCH Buffer;
|
||||||
|
ULONG Length;
|
||||||
|
ULONG Information = 0;
|
||||||
|
|
||||||
|
switch (Stack->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_CREATE:
|
||||||
|
DPRINT("Creating\n",0);
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_WRITE:
|
||||||
|
DPRINT("Writing %d bytes\n",
|
||||||
|
Stack->Parameters.Write.Length);
|
||||||
|
Length = Stack->Parameters.Write.Length;
|
||||||
|
if ((Length%512)>0)
|
||||||
|
{
|
||||||
|
Length = Length - (Length%512);
|
||||||
|
}
|
||||||
|
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||||
|
DPRINT("Buffer %x\n",Buffer);
|
||||||
|
#if 0
|
||||||
|
for (i=0;i<Length;i++)
|
||||||
|
{
|
||||||
|
if ((i%512)==0)
|
||||||
|
{
|
||||||
|
DPRINT("Offset %x\n",
|
||||||
|
Stack->Parameters.Write.ByteOffset.LowPart+i);
|
||||||
|
SdWriteOffset(Stack->Parameters.Write.ByteOffset.LowPart+i);
|
||||||
|
}
|
||||||
|
outb_p(PORT,Buffer[i]);
|
||||||
|
DbgPrint("%c",Buffer[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
for (i=0;i<(Length/512);i++)
|
||||||
|
{
|
||||||
|
DPRINT("Offset %x\n",
|
||||||
|
Stack->Parameters.Write.ByteOffset.LowPart+i);
|
||||||
|
SdWriteOffset(Stack->Parameters.Write.ByteOffset.LowPart+i);
|
||||||
|
outsb(PORT,Buffer,512);
|
||||||
|
}
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
Information = Length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_READ:
|
||||||
|
DPRINT("Reading %d bytes\n",
|
||||||
|
Stack->Parameters.Write.Length);
|
||||||
|
Length = Stack->Parameters.Write.Length;
|
||||||
|
if ((Length%512)>0)
|
||||||
|
{
|
||||||
|
Length = Length - (Length%512);
|
||||||
|
}
|
||||||
|
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||||
|
for (i=0;i<Length;i++)
|
||||||
|
{
|
||||||
|
if ((i%512)==0)
|
||||||
|
{
|
||||||
|
DPRINT("Offset %d\n",
|
||||||
|
Stack->Parameters.Write.ByteOffset.LowPart+i);
|
||||||
|
SdWriteOffset(Stack->Parameters.Write.ByteOffset.LowPart+i);
|
||||||
|
}
|
||||||
|
Buffer[i]=inb_p(PORT);
|
||||||
|
}
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = status;
|
||||||
|
Irp->IoStatus.Information = Information;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Called by the system to initalize the driver
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DriverObject = object describing this driver
|
||||||
|
* RegistryPath = path to our configuration entries
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
NTSTATUS ret;
|
||||||
|
ANSI_STRING astr;
|
||||||
|
UNICODE_STRING ustr;
|
||||||
|
ANSI_STRING asymlink;
|
||||||
|
UNICODE_STRING usymlink;
|
||||||
|
|
||||||
|
DbgPrint("Simple Disk Driver 0.0.1\n");
|
||||||
|
|
||||||
|
RtlInitAnsiString(&astr,"\\Device\\SDisk");
|
||||||
|
RtlAnsiStringToUnicodeString(&ustr,&astr,TRUE);
|
||||||
|
ret = IoCreateDevice(DriverObject,0,&ustr,
|
||||||
|
FILE_DEVICE_DISK,0,FALSE,&DeviceObject);
|
||||||
|
if (ret!=STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitAnsiString(&asymlink,"\\??\\C:");
|
||||||
|
RtlAnsiStringToUnicodeString(&usymlink,&asymlink,TRUE);
|
||||||
|
IoCreateSymbolicLink(&usymlink,&ustr);
|
||||||
|
|
||||||
|
DeviceObject->Flags=DO_DIRECT_IO;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_READ] = Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
|
||||||
|
DriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
1
reactos/drivers/dd/serial/makefile
Normal file
1
reactos/drivers/dd/serial/makefile
Normal file
|
@ -0,0 +1 @@
|
||||||
|
all: serial.o
|
150
reactos/drivers/dd/serial/serial.c
Normal file
150
reactos/drivers/dd/serial/serial.c
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
** Serial driver
|
||||||
|
** Written by Jason Filby (jasonfilby@yahoo.com)
|
||||||
|
** For ReactOS (www.sid-dis.com/reactos)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <internal/mmhal.h>
|
||||||
|
#include <internal/hal/io.h>
|
||||||
|
|
||||||
|
#define COM1 0x3F8
|
||||||
|
#define COM2 0x2F8
|
||||||
|
#define COM3 0x3E8
|
||||||
|
#define COM4 0x2E8
|
||||||
|
|
||||||
|
#define UART_BAUDRATE 96 // 1200 BPS
|
||||||
|
#define UART_LCRVAL 0x1b // 0x1b for 8e1
|
||||||
|
#define UARY_FCRVAL 0x7
|
||||||
|
|
||||||
|
int uart_detect(unsigned base)
|
||||||
|
{
|
||||||
|
// Returns 0 if no UART detected
|
||||||
|
|
||||||
|
int olddata=inb_p(base+4);
|
||||||
|
outb_p(base+4, 0x10);
|
||||||
|
if ((inb_p(base+6) & 0xf0)) return 0;
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
int irq_setup(unsigned base)
|
||||||
|
{
|
||||||
|
// Returns -1 if not found -- otherwise returns interrupt level
|
||||||
|
|
||||||
|
char ier, mcr, imrm, imrs, maskm, masks, irqm, irqs;
|
||||||
|
|
||||||
|
__asm("cli"); // disable all CPU interrupts
|
||||||
|
ier = inb_p(base+1); // read IER
|
||||||
|
outb_p(base+1,0); // disable all UART ints
|
||||||
|
while (!(inb_p(base+5)&0x20)); // wait for the THR to be empty
|
||||||
|
mcr = inb_p(base+4); // read MCR
|
||||||
|
outb_p(base+4,0x0F); // connect UART to irq line
|
||||||
|
imrm = inb_p(0x21); // read contents of master ICU mask register
|
||||||
|
imrs = inb_p(0xA1); // read contents of slave ICU mask register
|
||||||
|
outb_p(0xA0,0x0A); // next read access to 0xA0 reads out IRR
|
||||||
|
outb_p(0x20,0x0A); // next read access to 0x20 reads out IRR
|
||||||
|
outb_p(base+1,2); // let's generate interrupts...
|
||||||
|
maskm = inb_p(0x20); // this clears all bits except for the one
|
||||||
|
masks = inb_p(0xA0); // that corresponds to the int
|
||||||
|
outb_p(base+1,0); // drop the int line
|
||||||
|
maskm &= ~inb_p(0x20); // this clears all bits except for the one
|
||||||
|
masks &= ~inb_p(0xA0); // that corresponds to the int
|
||||||
|
outb_p(base+1,2); // and raise it again just to be sure...
|
||||||
|
maskm &= inb_p(0x20); // this clears all bits except for the one
|
||||||
|
masks &= inb_p(0xA0); // that corresponds to the int
|
||||||
|
outb_p(0xA1,~masks); // now let us unmask this interrupt only
|
||||||
|
outb_p(0x21,~maskm);
|
||||||
|
outb_p(0xA0,0x0C); // enter polled mode
|
||||||
|
outb_p(0x20,0x0C); // that order is important with Pentium/PCI systems
|
||||||
|
irqs = inb_p(0xA0); // and accept the interrupt
|
||||||
|
irqm = inb_p(0x20);
|
||||||
|
inb_p(base+2); // reset transmitter interrupt in UART
|
||||||
|
outb_p(base+4,mcr); // restore old value of MCR
|
||||||
|
outb_p(base+1,ier); // restore old value of IER
|
||||||
|
if (masks) outb_p(0xA0,0x20); // send an EOI to slave
|
||||||
|
if (maskm) outb_p(0x20,0x20); // send an EOI to master
|
||||||
|
outb_p(0x21,imrm); // restore old mask register contents
|
||||||
|
outb_p(0xA1,imrs);
|
||||||
|
__asm("sti");
|
||||||
|
if (irqs&0x80) // slave interrupt occured
|
||||||
|
return (irqs&0x07)+8;
|
||||||
|
if (irqm&0x80) // master interrupt occured
|
||||||
|
return irqm&0x07;
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
void uart_init(unsigned uart_base)
|
||||||
|
{
|
||||||
|
// Initialize the UART
|
||||||
|
outb_p(uart_base+3, 0x80);
|
||||||
|
outw_p(uart_base, UART_BAUDRATE);
|
||||||
|
outb_p(uart_base+3, UART_LCRVAL);
|
||||||
|
outb_p(uart_base+4, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned uart_getchar(unsigned uart_base)
|
||||||
|
{
|
||||||
|
unsigned x;
|
||||||
|
|
||||||
|
x=(inb_p(uart_base+5) & 0x9f) << 8;
|
||||||
|
if(x & 0x100) x|=((unsigned)inb_p(uart_base)) & 0xff;
|
||||||
|
return x;
|
||||||
|
};
|
||||||
|
|
||||||
|
void InitializeSerial(void)
|
||||||
|
{
|
||||||
|
unsigned comports[4] = { COM1, COM2, COM3, COM4 };
|
||||||
|
char *comname[4] = { "COM1", "COM2", "COM3", "COM4" };
|
||||||
|
int i, irq_level;
|
||||||
|
|
||||||
|
for (i=0; i<4; i++)
|
||||||
|
{
|
||||||
|
if(uart_detect(comports[i])==0)
|
||||||
|
{
|
||||||
|
printk("%s not detected\n", comname[i]);
|
||||||
|
} else {
|
||||||
|
uart_init(comports[i]);
|
||||||
|
irq_level=irq_setup(comports[i]);
|
||||||
|
if(irq_level==-1)
|
||||||
|
{
|
||||||
|
printk("Warning: IRQ not detected!\n");
|
||||||
|
} else {
|
||||||
|
printk("%s hooked to interrupt level %d\n", comname[i], irq_level);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// For testing purposes
|
||||||
|
void testserial()
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
char testc;
|
||||||
|
|
||||||
|
union {
|
||||||
|
unsigned val;
|
||||||
|
char character;
|
||||||
|
} x;
|
||||||
|
|
||||||
|
printk("Testing serial input...\n");
|
||||||
|
|
||||||
|
while(i==0) {
|
||||||
|
x.val=uart_getchar(COM1);
|
||||||
|
// if(!x.val) continue;
|
||||||
|
// if(x.val & 0x100)
|
||||||
|
|
||||||
|
testc=inb_p(COM1);
|
||||||
|
|
||||||
|
// printk("(%x-%c) %c\n", x.val, x.character, testc);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
|
{
|
||||||
|
printk("Serial Driver 0.0.2\n");
|
||||||
|
InitializeSerial();
|
||||||
|
// testserial();
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
};
|
||||||
|
|
61
reactos/drivers/dd/sound/dsp.c
Normal file
61
reactos/drivers/dd/sound/dsp.c
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/************************************
|
||||||
|
* unsigned char read_dsp(void)
|
||||||
|
*
|
||||||
|
* Reads the DSP chip
|
||||||
|
* Arguments: none
|
||||||
|
* Returns: Byte read
|
||||||
|
************************************/
|
||||||
|
unsigned char read_dsp(unsigned short base)
|
||||||
|
{
|
||||||
|
while((inb(base+0x0e)&0x80)==0); //Wait until there is something to read
|
||||||
|
return inb(base+0x0a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************'
|
||||||
|
* sb_status detect_dsp(void);
|
||||||
|
*
|
||||||
|
* Detects if a SB16 is installed
|
||||||
|
* Arguments: None
|
||||||
|
* Returns: Success or failure
|
||||||
|
************************************/
|
||||||
|
sb_status detect_dsp(SB16* sb16)
|
||||||
|
{
|
||||||
|
for(base=0x200;base<0x280;base+=0x10) //Tries to reset all DSP addresses there is
|
||||||
|
if(reset_dsp(base)==SB_TRUE)
|
||||||
|
{
|
||||||
|
sb16->base=base;
|
||||||
|
return SB_TRUE;
|
||||||
|
}
|
||||||
|
return SB_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************
|
||||||
|
* sb_status reset_dsp(unsigned short base_address);
|
||||||
|
*
|
||||||
|
* Tries to reset a DSP chip
|
||||||
|
* Arguments: base address
|
||||||
|
* Returns: Success of failure
|
||||||
|
**************************************/
|
||||||
|
sb_status reset_dsp(unsigned short base_address)
|
||||||
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
|
outb(base_address+DSP_RESET_PORT,1);
|
||||||
|
for(delay=0;delay<0xffff;delay++);
|
||||||
|
|
||||||
|
outb(base_address+DSP_RESET_PORT,0);
|
||||||
|
for(delay=0;delay<0xffff;delay++);
|
||||||
|
|
||||||
|
if((inb(base_address+DSP_READ_STATUS_PORT)&0x80)==0) return SB_FALSE;
|
||||||
|
|
||||||
|
if(inb(base_address+DSP_READ_DATA_PORT)!=0xAA) return SB_FALSE;
|
||||||
|
|
||||||
|
return SB_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_dsp(unsigned short base,unsigned char data)
|
||||||
|
{
|
||||||
|
while ((inb(base+DSP_WRITE_PORT) & 0x80) != 0);
|
||||||
|
outb(base+DSP_WRITE_PORT, data);
|
||||||
|
}
|
||||||
|
|
17
reactos/drivers/dd/sound/dsp.h
Normal file
17
reactos/drivers/dd/sound/dsp.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#define SB_TRUE 0
|
||||||
|
#define SB_FALSE 1
|
||||||
|
|
||||||
|
#define DSP_MIXER_ADDRESS_PORT 0x04
|
||||||
|
#define DSP_MIXER_DATA_PORT 0x05
|
||||||
|
#define DSP_RESET_PORT 0x06
|
||||||
|
#define DSP_READ_DATA_PORT 0x0A
|
||||||
|
#define DSP_WRITE_PORT 0x0C //Same port used for reading status and writing data
|
||||||
|
#define DSP_READ_STATUS_PORT 0x0E
|
||||||
|
|
||||||
|
typedef unsigned char sb_status;
|
||||||
|
unsigned short base;
|
||||||
|
unsigned char irq,dma8,dma16;
|
||||||
|
unsigned char read_dsp(unsigned short base);
|
||||||
|
void write_dsp(unsigned short base,unsigned char data);
|
||||||
|
sb_status detect_dsp(SB16* sb16);
|
||||||
|
sb_status reset_dsp(unsigned short base_address);
|
2
reactos/drivers/dd/sound/makefile
Normal file
2
reactos/drivers/dd/sound/makefile
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
sound.o: sound.c dsp.c mixer.c wave.h wave.c
|
||||||
|
all: sound.o
|
32
reactos/drivers/dd/sound/mixer.c
Normal file
32
reactos/drivers/dd/sound/mixer.c
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
unsigned char read_mixer(unsigned short base,unsigned char reg)
|
||||||
|
{
|
||||||
|
|
||||||
|
outb(base+0x04,reg);
|
||||||
|
return inb(base+0x05);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char get_irq(SB16* sb16)
|
||||||
|
{
|
||||||
|
unsigned char irq;
|
||||||
|
irq=(read_mixer(sb16->base,MIXER_INTERRUPT_SETUP_REGISTER)&0x0f);
|
||||||
|
|
||||||
|
if(irq==1) sb16->irq=2;
|
||||||
|
if(irq==2) sb16->irq=5;
|
||||||
|
if(irq==4) sb16->irq=7;
|
||||||
|
if(irq==8) sb16->irq=10;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_dma(SB16* sb16)
|
||||||
|
{
|
||||||
|
unsigned char hi,lo,result=read_mixer(sb16->base,MIXER_DMA_SETUP_REGISTER);
|
||||||
|
hi=result&0xE0;
|
||||||
|
lo=result&0x0B;
|
||||||
|
if(hi==0x80) sb16->dma16=7;
|
||||||
|
if(hi==0x40) sb16->dma16=6;
|
||||||
|
if(hi==0x20) sb16->dma16=5;
|
||||||
|
|
||||||
|
if(lo==0x08) sb16->dma8=3;
|
||||||
|
if(lo==0x02) sb16->dma8=1;
|
||||||
|
if(lo==0x01) sb16->dma8=0;
|
||||||
|
}
|
8
reactos/drivers/dd/sound/mixer.h
Normal file
8
reactos/drivers/dd/sound/mixer.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#define MIXER_INTERRUPT_SETUP_REGISTER 0x80
|
||||||
|
#define MIXER_DMA_SETUP_REGISTER 0x81
|
||||||
|
#define MIXER_INTERRUP_STATUS_REGISTEER 0x82
|
||||||
|
|
||||||
|
void get_dma(SB16* sb16);
|
||||||
|
unsigned char read_mixer(unsigned short base,unsigned char reg);
|
||||||
|
unsigned char get_irq(SB16* sb16);
|
||||||
|
|
9
reactos/drivers/dd/sound/sb16.h
Normal file
9
reactos/drivers/dd/sound/sb16.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned short base;
|
||||||
|
unsigned char irq;
|
||||||
|
unsigned char dma8;
|
||||||
|
unsigned char dma16;
|
||||||
|
unsigned char* buffer;
|
||||||
|
}SB16;
|
||||||
|
|
3
reactos/drivers/dd/sound/sb_waveout.c
Normal file
3
reactos/drivers/dd/sound/sb_waveout.c
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
void write_wave()
|
||||||
|
{
|
||||||
|
}
|
123
reactos/drivers/dd/sound/sound.c
Normal file
123
reactos/drivers/dd/sound/sound.c
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: mkernel/modules/sound/sound.c
|
||||||
|
* PURPOSE: SoundBlaster 16 Driver
|
||||||
|
* PROGRAMMER: Snatched from David Welch (welch@mcmail.com)
|
||||||
|
* Modified for Soundblaster by Robert Bergkvist (fragdance@hotmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* ??/??/??: Created
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FUNCTIONS **************************************************************/
|
||||||
|
|
||||||
|
#include <internal/hal/io.h>
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/hal/ddk.h>
|
||||||
|
#include <internal/dma.h>
|
||||||
|
#include <internal/mm.h>
|
||||||
|
#include <internal/string.h>
|
||||||
|
#include <devices.h>
|
||||||
|
#include "sb16.h"
|
||||||
|
#include "dsp.h"
|
||||||
|
#include "mixer.h"
|
||||||
|
#include "in.h"
|
||||||
|
#include "wave.h"
|
||||||
|
|
||||||
|
|
||||||
|
SB16 sb16;
|
||||||
|
sb_status sb16_getenvironment(void);
|
||||||
|
|
||||||
|
NTSTATUS Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Handles user mode requests
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DeviceObject = Device for request
|
||||||
|
* Irp = I/O request packet describing request
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
switch (Stack->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_CREATE:
|
||||||
|
printk("(SoundBlaster 16 Driver WaveOut) Creating\n");
|
||||||
|
reset_dsp(sb16.base);
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_WRITE:
|
||||||
|
printk("(SoundBlaster 16 Driver) Writing %d bytes\n",Stack->Parameters.Write.Length);
|
||||||
|
sb16_play((WAVE_HDR*)Irp->UserBuffer);
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS ModuleEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Called by the system to initalize the driver
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DriverObject = object describing this driver
|
||||||
|
* RegistryPath = path to our configuration entries
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
NTSTATUS ret;
|
||||||
|
|
||||||
|
printk("SoundBlaster 16 Driver 0.0.1\n");
|
||||||
|
if(sb16_getenvironment()!=SB_TRUE)
|
||||||
|
{
|
||||||
|
printk("Soundblaster 16 not found\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ret = IoCreateDevice(DriverObject,0,"\\Device\\WaveOut",FILE_DEVICE_WAVE_OUT,0,FALSE,&DeviceObject);
|
||||||
|
if (ret!=STATUS_SUCCESS)
|
||||||
|
return(ret);
|
||||||
|
|
||||||
|
DeviceObject->Flags=0;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] =Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
|
||||||
|
DriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
sb_status sb16_getenvironment(void)
|
||||||
|
{
|
||||||
|
if(detect_dsp(&sb16)!=SB_TRUE)
|
||||||
|
{
|
||||||
|
printk("Detect DSP failed!!!\n");
|
||||||
|
return SB_FALSE;
|
||||||
|
}
|
||||||
|
printk("DSP base address 0x%x\n",sb16.base);
|
||||||
|
get_irq(&sb16);
|
||||||
|
printk("IRQ: %d\n",sb16.irq);
|
||||||
|
get_dma(&sb16);
|
||||||
|
printk("DMA8: 0x%x DMA16: 0x%x\n",sb16.dma8,sb16.dma16);
|
||||||
|
return SB_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "dsp.c"
|
||||||
|
#include "mixer.c"
|
||||||
|
#include "wave.c"
|
24
reactos/drivers/dd/sound/wave.h
Normal file
24
reactos/drivers/dd/sound/wave.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
KIRQL irql;
|
||||||
|
KAFFINITY affinity;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char rID[4] __attribute__((packed)); //4 0
|
||||||
|
unsigned int rLen __attribute__((packed)); //4 4
|
||||||
|
unsigned char wID[4] __attribute__((packed)); //4 8
|
||||||
|
unsigned char fID[4] __attribute__((packed)); //4 12
|
||||||
|
unsigned int fLen __attribute__((packed)); //4 16
|
||||||
|
unsigned short wFormatTag __attribute__((packed)); //2 18
|
||||||
|
unsigned short nChannels __attribute__((packed)); //2 20
|
||||||
|
unsigned int nSamplesPerSec __attribute__((packed)); //2 22
|
||||||
|
unsigned int nAvgBytesPerSec __attribute__((packed)); //2 24
|
||||||
|
unsigned short nBlockAlign __attribute__((packed)); //2 26
|
||||||
|
unsigned short FormatSpecific __attribute__((packed)); //2 28
|
||||||
|
unsigned char dID[4] __attribute__((packed)); //4 30
|
||||||
|
unsigned int dLen __attribute__((packed));
|
||||||
|
unsigned char* data;
|
||||||
|
}WAVE_HDR;
|
||||||
|
|
||||||
|
void sb16_play(WAVE_HDR* wave);
|
||||||
|
void dump_wav(WAVE_HDR* wave);
|
||||||
|
BOOLEAN playRoutine(PKINTERRUPT Interrupt,PVOID ServiceContext);
|
1
reactos/drivers/dd/test/makefile
Normal file
1
reactos/drivers/dd/test/makefile
Normal file
|
@ -0,0 +1 @@
|
||||||
|
all: test.o
|
102
reactos/drivers/dd/test/test.c
Normal file
102
reactos/drivers/dd/test/test.c
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/test/test.c
|
||||||
|
* PURPOSE: Testing driver
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* ??/??/??: Created
|
||||||
|
* 18/06/98: Made more NT like
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
|
||||||
|
/* FUNCTIONS **************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS TestWrite(PIRP Irp, PIO_STACK_LOCATION Stk)
|
||||||
|
{
|
||||||
|
PVOID Address;
|
||||||
|
|
||||||
|
Address = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||||
|
printk("Asked to write '%s'\n",(PCH)Address);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS TestDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Handles user mode requests
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DeviceObject = Device for request
|
||||||
|
* Irp = I/O request packet describing request
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
NTSTATUS status;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch (Stack->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_CREATE:
|
||||||
|
printk("(Test Driver) Creating\n");
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_WRITE:
|
||||||
|
printk("(Test Driver) Writing\n");
|
||||||
|
status = TestWrite(Irp,Stack);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Called by the system to initalize the driver
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DriverObject = object describing this driver
|
||||||
|
* RegistryPath = path to our configuration entries
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
NTSTATUS ret;
|
||||||
|
ANSI_STRING astr;
|
||||||
|
UNICODE_STRING ustr;
|
||||||
|
|
||||||
|
printk("Test Driver 0.0.1\n");
|
||||||
|
|
||||||
|
RtlInitAnsiString(&astr,"\\Device\\Test");
|
||||||
|
RtlAnsiStringToUnicodeString(&ustr,&astr,TRUE);
|
||||||
|
ret = IoCreateDevice(DriverObject,0,&ustr,
|
||||||
|
FILE_DEVICE_PARALLEL_PORT,0,FALSE,&DeviceObject);
|
||||||
|
if (ret!=STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceObject->Flags=DO_DIRECT_IO;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = TestDispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = TestDispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = TestDispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = TestDispatch;
|
||||||
|
DriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
1
reactos/drivers/dd/test1/makefile
Normal file
1
reactos/drivers/dd/test1/makefile
Normal file
|
@ -0,0 +1 @@
|
||||||
|
all: test.o
|
65
reactos/drivers/dd/test1/test.c
Normal file
65
reactos/drivers/dd/test1/test.c
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/test1/test.c
|
||||||
|
* PURPOSE: Bug demonstration
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* ??/??/??: Created
|
||||||
|
* 18/06/98: Made more NT like
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FUNCTIONS **************************************************************/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <internal/kernel.h>
|
||||||
|
#include <internal/hal/io.h>
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
#define IDE_NT_ROOTDIR_NAME "\\Device\\"
|
||||||
|
#define IDE_NT_DEVICE_NAME "\\HardDrive"
|
||||||
|
|
||||||
|
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Called by the system to initalize the driver
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DriverObject = object describing this driver
|
||||||
|
* RegistryPath = path to our configuration entries
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
char DeviceDirName[255];
|
||||||
|
UNICODE_STRING UnicodeDeviceDirName;
|
||||||
|
ANSI_STRING AnsiDeviceDirName;
|
||||||
|
OBJECT_ATTRIBUTES DeviceDirAttributes;
|
||||||
|
HANDLE Handle;
|
||||||
|
NTSTATUS RC;
|
||||||
|
ULONG HarddiskIdx = 0;
|
||||||
|
|
||||||
|
strcpy(DeviceDirName,IDE_NT_ROOTDIR_NAME);
|
||||||
|
strcat(DeviceDirName,IDE_NT_DEVICE_NAME);
|
||||||
|
DeviceDirName[strlen(DeviceDirName)+1]='\0';
|
||||||
|
DeviceDirName[strlen(DeviceDirName)]= '0' + HarddiskIdx;
|
||||||
|
printk("DeviceDirName %s\n",DeviceDirName);
|
||||||
|
RtlInitAnsiString(&AnsiDeviceDirName,DeviceDirName);
|
||||||
|
RC = RtlAnsiStringToUnicodeString(&UnicodeDeviceDirName,
|
||||||
|
&AnsiDeviceDirName,
|
||||||
|
TRUE);
|
||||||
|
if (!NT_SUCCESS(RC))
|
||||||
|
{
|
||||||
|
DPRINT("Could not convert ansi to unicode for device dir\n",0);
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
InitializeObjectAttributes(&DeviceDirAttributes,&UnicodeDeviceDirName,
|
||||||
|
0,NULL,NULL);
|
||||||
|
RC = ZwCreateDirectoryObject(&Handle,0,&DeviceDirAttributes);
|
||||||
|
if (!NT_SUCCESS(RC))
|
||||||
|
{
|
||||||
|
DPRINT("Could not create device dir\n",0);
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
RtlFreeUnicodeString(&UnicodeDeviceDirName);
|
||||||
|
}
|
||||||
|
|
78
reactos/drivers/fs/minix/block.c
Normal file
78
reactos/drivers/fs/minix/block.c
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/fs/minix/minix.c
|
||||||
|
* PURPOSE: Minix FSD
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/string.h>
|
||||||
|
#include <wstring.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
#include "minix.h"
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
static unsigned int MinixGetBlock(PMINIX_DEVICE_EXTENSION DeviceExt,
|
||||||
|
struct minix_inode* inode,
|
||||||
|
int blk)
|
||||||
|
{
|
||||||
|
int block;
|
||||||
|
PCCB Ccb;
|
||||||
|
|
||||||
|
DPRINT("MinixGetBlock(inode %x, blk %d)\n",inode,blk);
|
||||||
|
|
||||||
|
if (blk < 7)
|
||||||
|
{
|
||||||
|
block = inode->i_zone[blk];
|
||||||
|
return(block);
|
||||||
|
}
|
||||||
|
blk = blk - 7;
|
||||||
|
|
||||||
|
if (blk < 512)
|
||||||
|
{
|
||||||
|
block = inode->i_zone[7];
|
||||||
|
Ccb = CbAcquireForRead(&DeviceExt->Dccb,block);
|
||||||
|
block = ((PUSHORT)Ccb->Buffer)[blk];
|
||||||
|
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
|
||||||
|
return(block);
|
||||||
|
}
|
||||||
|
blk = blk - 512;
|
||||||
|
block = inode->i_zone[8];
|
||||||
|
|
||||||
|
Ccb = CbAcquireForRead(&DeviceExt->Dccb,block);
|
||||||
|
block = ((PUSHORT)Ccb->Buffer)[(blk>>9)&511];
|
||||||
|
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
|
||||||
|
|
||||||
|
Ccb = CbAcquireForRead(&DeviceExt->Dccb,block);
|
||||||
|
block = ((PUSHORT)Ccb->Buffer)[blk&512];
|
||||||
|
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
|
||||||
|
|
||||||
|
return(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS MinixReadBlock(PMINIX_DEVICE_EXTENSION DeviceExt,
|
||||||
|
struct minix_inode* inode,
|
||||||
|
int blk,
|
||||||
|
PCCB* Ccb)
|
||||||
|
{
|
||||||
|
unsigned int block;
|
||||||
|
|
||||||
|
DPRINT("DeviceExt %x\n",DeviceExt);
|
||||||
|
DPRINT("inode %x\n",inode);
|
||||||
|
DPRINT("blk %d\n",blk);
|
||||||
|
DPRINT("Ccb %x\n",Ccb);
|
||||||
|
DPRINT("MinixReadBlock(DeviceExt %x, inode %x, blk %d, Ccb %x)\n",
|
||||||
|
DeviceExt,inode,blk,Ccb);
|
||||||
|
|
||||||
|
block = MinixGetBlock(DeviceExt,inode,blk);
|
||||||
|
(*Ccb) = CbAcquireForRead(&DeviceExt->Dccb,block);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
199
reactos/drivers/fs/minix/dir.c
Normal file
199
reactos/drivers/fs/minix/dir.c
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/fs/minix/minix.c
|
||||||
|
* PURPOSE: Minix FSD
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/string.h>
|
||||||
|
#include <wstring.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
#include "minix.h"
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
BOOLEAN MinixCompareUnicodeStringToAnsi(PCH AnsiStr, PWCHAR UnicodeStr,
|
||||||
|
ULONG MaxLen)
|
||||||
|
{
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
while (i<MaxLen)
|
||||||
|
{
|
||||||
|
if ((*AnsiStr)!=(*UnicodeStr))
|
||||||
|
{
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
if ((*AnsiStr)==0 && (*UnicodeStr)==0)
|
||||||
|
{
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
AnsiStr++;
|
||||||
|
UnicodeStr++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ENTRIES_PER_BLOCK (BLOCKSIZE / MINIX_DIR_ENTRY_SIZE)
|
||||||
|
|
||||||
|
ULONG MinixDirLookup(PMINIX_DEVICE_EXTENSION DeviceExt,
|
||||||
|
struct minix_inode* dir,
|
||||||
|
PWCHAR Name)
|
||||||
|
{
|
||||||
|
struct minix_dir_entry* current_entry = NULL;
|
||||||
|
unsigned int offset;
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int inode;
|
||||||
|
PCCB Ccb = NULL;
|
||||||
|
|
||||||
|
DPRINT("MinixDirLookup(DeviceExt %x, dir %x, Name %w)\n",DeviceExt,dir,
|
||||||
|
Name);
|
||||||
|
|
||||||
|
for (i=0;i<(dir->i_size/MINIX_DIR_ENTRY_SIZE);i++)
|
||||||
|
{
|
||||||
|
CHECKPOINT;
|
||||||
|
offset = i*MINIX_DIR_ENTRY_SIZE;
|
||||||
|
if ((offset%BLOCKSIZE)==0)
|
||||||
|
{
|
||||||
|
CHECKPOINT;
|
||||||
|
if (Ccb != NULL)
|
||||||
|
{
|
||||||
|
CHECKPOINT;
|
||||||
|
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
|
||||||
|
}
|
||||||
|
CHECKPOINT;
|
||||||
|
MinixReadBlock(DeviceExt,
|
||||||
|
dir,
|
||||||
|
offset/BLOCKSIZE,
|
||||||
|
&Ccb);
|
||||||
|
}
|
||||||
|
current_entry = (struct minix_dir_entry *)
|
||||||
|
(Ccb->Buffer+offset%BLOCKSIZE);
|
||||||
|
DPRINT("Inode %x Name %.30s\n",current_entry->inode,
|
||||||
|
current_entry->name);
|
||||||
|
if (MinixCompareUnicodeStringToAnsi(current_entry->name,
|
||||||
|
Name,30))
|
||||||
|
{
|
||||||
|
inode = current_entry->inode;
|
||||||
|
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
|
||||||
|
DPRINT("MinixDirLookup() = %d\n",inode);
|
||||||
|
return(inode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CHECKPOINT;
|
||||||
|
if (Ccb != NULL)
|
||||||
|
{
|
||||||
|
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
|
||||||
|
}
|
||||||
|
DPRINT("MinixDirLookup() = %d\n",0);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS MinixOpen(PDEVICE_OBJECT DeviceObject,
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||||
|
PWSTR DeviceName,
|
||||||
|
struct minix_inode* result,
|
||||||
|
PULONG Information)
|
||||||
|
{
|
||||||
|
PWSTR current;
|
||||||
|
PWSTR next;
|
||||||
|
PWSTR string = DeviceName;
|
||||||
|
struct minix_inode current_dir;
|
||||||
|
unsigned int current_ino;
|
||||||
|
|
||||||
|
DbgPrint("MinixOpen(DeviceObject %x, DeviceName %w, result %x)\n",
|
||||||
|
DeviceObject,DeviceName,result);
|
||||||
|
DPRINT("DeviceName %x\n",DeviceName);
|
||||||
|
|
||||||
|
next = &string[0];
|
||||||
|
current = next+1;
|
||||||
|
|
||||||
|
current_ino = MINIX_ROOT_INO;
|
||||||
|
|
||||||
|
while (next!=NULL && current_ino!=0)
|
||||||
|
{
|
||||||
|
MinixReadInode(DeviceObject,DeviceExt,current_ino,¤t_dir);
|
||||||
|
|
||||||
|
DPRINT("current %w next %x\n",current,next);
|
||||||
|
|
||||||
|
*next = '\\';
|
||||||
|
current = next+1;
|
||||||
|
next = wcschr(next+1,'\\');
|
||||||
|
if (next!=NULL)
|
||||||
|
{
|
||||||
|
*next=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_ino = MinixDirLookup(DeviceExt,¤t_dir,current);
|
||||||
|
}
|
||||||
|
if (next==NULL && current_ino!=0)
|
||||||
|
{
|
||||||
|
MinixReadInode(DeviceObject,DeviceExt,current_ino,¤t_dir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*Information) = FILE_DOES_NOT_EXIST;
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
memcpy(result,¤t_dir,sizeof(struct minix_inode));
|
||||||
|
DPRINT("MinxOpen() = STATUS_SUCCESS\n",0);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS MinixClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
|
|
||||||
|
DPRINT("MinixClose(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||||
|
|
||||||
|
ExFreePool(FileObject->FsContext);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS MinixCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
|
NTSTATUS Status;
|
||||||
|
struct minix_inode* result;
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt;
|
||||||
|
|
||||||
|
DPRINT("MinixCreate(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
||||||
|
DPRINT("Opening file %x %w\n",FileObject->FileName.Buffer,
|
||||||
|
FileObject->FileName.Buffer);
|
||||||
|
DPRINT("FileObject->FileName.Buffer %x\n",
|
||||||
|
FileObject->FileName.Buffer);
|
||||||
|
|
||||||
|
DeviceExt = (MINIX_DEVICE_EXTENSION *)DeviceObject->DeviceExtension;
|
||||||
|
result = ExAllocatePool(NonPagedPool,sizeof(struct minix_inode));
|
||||||
|
DPRINT("result %x\n",result);
|
||||||
|
Status = MinixOpen(DeviceExt->AttachedDevice,DeviceExt,
|
||||||
|
FileObject->FileName.Buffer,result,
|
||||||
|
&Irp->IoStatus.Information);
|
||||||
|
|
||||||
|
if (Status==STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
FileObject->FsContext=result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
131
reactos/drivers/fs/minix/inode.c
Normal file
131
reactos/drivers/fs/minix/inode.c
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/fs/minix/minix.c
|
||||||
|
* PURPOSE: Minix FSD
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/string.h>
|
||||||
|
#include <internal/bitops.h>
|
||||||
|
#include <ddk/ntifs.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
#include "minix.h"
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS MinixDeleteInode(PDEVICE_OBJECT Volume,
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||||
|
ULONG ino)
|
||||||
|
{
|
||||||
|
PULONG Buffer;
|
||||||
|
ULONG off;
|
||||||
|
|
||||||
|
Buffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||||
|
MinixReadSector(Volume, (ino / 8192)+2, (PVOID)Buffer);
|
||||||
|
off = ino % 8192;
|
||||||
|
clear_bit(off%32,&Buffer[off/32]);
|
||||||
|
MinixWriteSector(Volume, (ino / 8192)+2, (PVOID)Buffer);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG MinixAllocateInode(PDEVICE_OBJECT Volume,
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
PULONG Buffer;
|
||||||
|
ULONG ino;
|
||||||
|
|
||||||
|
Buffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||||
|
for (i=0; i<DeviceExt->sb->s_imap_blocks; i++)
|
||||||
|
{
|
||||||
|
MinixReadSector(Volume,i + 2,Buffer);
|
||||||
|
ino = find_first_zero_bit(Buffer,8192);
|
||||||
|
if (ino < 8192)
|
||||||
|
{
|
||||||
|
set_bit(ino%32,&Buffer[32]);
|
||||||
|
MinixWriteSector(Volume,i + 2,Buffer);
|
||||||
|
ExFreePool(Buffer);
|
||||||
|
return(ino + (i*8192));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExFreePool(Buffer);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG MinixNewInode(PDEVICE_OBJECT Volume,
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||||
|
struct minix_inode* new_inode)
|
||||||
|
{
|
||||||
|
ULONG ino;
|
||||||
|
|
||||||
|
ino = MinixAllocateInode(Volume,DeviceExt);
|
||||||
|
if (ino == 0)
|
||||||
|
{
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
MinixWriteInode(Volume,DeviceExt,ino,new_inode);
|
||||||
|
return(ino);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS MinixWriteInode(PDEVICE_OBJECT Volume,
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||||
|
ULONG ino,
|
||||||
|
struct minix_inode* result)
|
||||||
|
{
|
||||||
|
int block;
|
||||||
|
char* buffer;
|
||||||
|
struct minix_inode* inodes;
|
||||||
|
|
||||||
|
DPRINT("MinixWriteInode(ino %x, result %x)\n",ino,result);
|
||||||
|
|
||||||
|
buffer = ExAllocatePool(NonPagedPool,1024);
|
||||||
|
inodes = (struct minix_inode *)buffer;
|
||||||
|
|
||||||
|
block = 2 + DeviceExt->sb->s_imap_blocks + DeviceExt->sb->s_zmap_blocks
|
||||||
|
+ ((ino-1) / MINIX_INODES_PER_BLOCK);
|
||||||
|
MinixReadSector(Volume,block,buffer);
|
||||||
|
memcpy(&inodes[(ino-1)%MINIX_INODES_PER_BLOCK],result,
|
||||||
|
sizeof(struct minix_inode));
|
||||||
|
MinixWriteSector(Volume,block,buffer);
|
||||||
|
|
||||||
|
ExFreePool(buffer);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS MinixReadInode(PDEVICE_OBJECT DeviceObject,
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||||
|
ULONG ino,
|
||||||
|
struct minix_inode* result)
|
||||||
|
{
|
||||||
|
PCCB Ccb;
|
||||||
|
int block;
|
||||||
|
struct minix_inode* inodes;
|
||||||
|
|
||||||
|
DPRINT("MinixReadInode(ino %x, result %x)\n",ino,result);
|
||||||
|
|
||||||
|
block = 2 + DeviceExt->sb->s_imap_blocks + DeviceExt->sb->s_zmap_blocks
|
||||||
|
+ ((ino-1) / MINIX_INODES_PER_BLOCK);
|
||||||
|
DPRINT("Reading block %x offset %x\n",block,block*BLOCKSIZE);
|
||||||
|
DPRINT("Index %x\n",(ino-1)%MINIX_INODES_PER_BLOCK);
|
||||||
|
|
||||||
|
Ccb = CbAcquireForRead(&DeviceExt->Dccb,
|
||||||
|
block);
|
||||||
|
inodes = (struct minix_inode *)Ccb->Buffer;
|
||||||
|
|
||||||
|
memcpy(result,&inodes[(ino-1)%MINIX_INODES_PER_BLOCK],
|
||||||
|
sizeof(struct minix_inode));
|
||||||
|
DPRINT("result->i_uid %x\n",result->i_uid);
|
||||||
|
DPRINT("result->i_size %x\n",result->i_size);
|
||||||
|
|
||||||
|
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
122
reactos/drivers/fs/minix/minix.h
Normal file
122
reactos/drivers/fs/minix/minix.h
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <ddk/ntifs.h>
|
||||||
|
|
||||||
|
#define MINIX_ROOT_INO 1
|
||||||
|
|
||||||
|
/* Not the same as the bogus LINK_MAX in <linux/limits.h>. Oh well. */
|
||||||
|
#define MINIX_LINK_MAX 250
|
||||||
|
|
||||||
|
#define MINIX_I_MAP_SLOTS 8
|
||||||
|
#define MINIX_Z_MAP_SLOTS 64
|
||||||
|
#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */
|
||||||
|
#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */
|
||||||
|
#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */
|
||||||
|
#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */
|
||||||
|
#define MINIX_VALID_FS 0x0001 /* Clean fs. */
|
||||||
|
#define MINIX_ERROR_FS 0x0002 /* fs has errors. */
|
||||||
|
|
||||||
|
#define MINIX_INODES_PER_BLOCK ((BLOCKSIZE)/(sizeof (struct minix_inode)))
|
||||||
|
#define MINIX2_INODES_PER_BLOCK ((BLOCKSIZE)/(sizeof (struct minix2_inode)))
|
||||||
|
|
||||||
|
#define MINIX_V1 0x0001 /* original minix fs */
|
||||||
|
#define MINIX_V2 0x0002 /* minix V2 fs */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the original minix inode layout on disk.
|
||||||
|
* Note the 8-bit gid and atime and ctime.
|
||||||
|
*/
|
||||||
|
struct minix_inode {
|
||||||
|
unsigned short int i_mode;
|
||||||
|
unsigned short int i_uid;
|
||||||
|
unsigned long i_size;
|
||||||
|
unsigned long i_time;
|
||||||
|
unsigned char i_gid;
|
||||||
|
unsigned char i_nlinks;
|
||||||
|
unsigned short int i_zone[9];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The new minix inode has all the time entries, as well as
|
||||||
|
* long block numbers and a third indirect block (7+1+1+1
|
||||||
|
* instead of 7+1+1). Also, some previously 8-bit values are
|
||||||
|
* now 16-bit. The inode is now 64 bytes instead of 32.
|
||||||
|
*/
|
||||||
|
struct minix2_inode {
|
||||||
|
unsigned short int i_mode;
|
||||||
|
unsigned short int i_nlinks;
|
||||||
|
unsigned short int i_uid;
|
||||||
|
unsigned short int i_gid;
|
||||||
|
unsigned long i_size;
|
||||||
|
unsigned long i_atime;
|
||||||
|
unsigned long i_mtime;
|
||||||
|
unsigned long i_ctime;
|
||||||
|
unsigned long i_zone[10];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* minix super-block data on disk
|
||||||
|
*/
|
||||||
|
struct minix_super_block {
|
||||||
|
unsigned short int s_ninodes;
|
||||||
|
unsigned short int s_nzones;
|
||||||
|
unsigned short int s_imap_blocks;
|
||||||
|
unsigned short int s_zmap_blocks;
|
||||||
|
unsigned short int s_firstdatazone;
|
||||||
|
unsigned short int s_log_zone_size;
|
||||||
|
unsigned long s_max_size;
|
||||||
|
unsigned short int s_magic;
|
||||||
|
unsigned short int s_state;
|
||||||
|
unsigned long s_zones;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct minix_dir_entry {
|
||||||
|
unsigned short int inode;
|
||||||
|
char name[0];
|
||||||
|
};
|
||||||
|
#define MINIX_DIR_ENTRY_SIZE (sizeof(struct minix_dir_entry)+30)
|
||||||
|
|
||||||
|
BOOLEAN MinixReadSector(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
|
IN ULONG DiskSector,
|
||||||
|
IN UCHAR* Buffer);
|
||||||
|
BOOLEAN MinixWriteSector(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
|
IN ULONG DiskSector,
|
||||||
|
IN UCHAR* Buffer);
|
||||||
|
|
||||||
|
#define BLOCKSIZE (1024)
|
||||||
|
|
||||||
|
//extern PDRIVER_OBJECT DriverObject;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT AttachedDevice;
|
||||||
|
struct minix_inode root_inode;
|
||||||
|
char superblock_buf[BLOCKSIZE];
|
||||||
|
struct minix_super_block* sb;
|
||||||
|
DCCB Dccb;
|
||||||
|
} MINIX_DEVICE_EXTENSION, *PMINIX_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
NTSTATUS MinixCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
NTSTATUS MinixClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
NTSTATUS MinixWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
NTSTATUS MinixRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
|
||||||
|
ULONG MinixNewInode(PDEVICE_OBJECT Volume,
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||||
|
struct minix_inode* new_inode);
|
||||||
|
NTSTATUS MinixWriteInode(PDEVICE_OBJECT Volume,
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||||
|
ULONG ino,
|
||||||
|
struct minix_inode* result);
|
||||||
|
NTSTATUS MinixReadInode(PDEVICE_OBJECT DeviceObject,
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||||
|
ULONG ino,
|
||||||
|
struct minix_inode* result);
|
||||||
|
NTSTATUS MinixDeleteInode(PDEVICE_OBJECT Volume,
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||||
|
ULONG ino);
|
||||||
|
|
||||||
|
NTSTATUS MinixReadBlock(PMINIX_DEVICE_EXTENSION DeviceExt,
|
||||||
|
struct minix_inode* inode,
|
||||||
|
int blk,
|
||||||
|
PCCB* Ccb);
|
156
reactos/drivers/fs/minix/minix.sym
Normal file
156
reactos/drivers/fs/minix/minix.sym
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
U _CbAcquireForRead
|
||||||
|
U _CbInitDccb
|
||||||
|
U _CbReleaseFromRead
|
||||||
|
U _DbgPrint
|
||||||
|
U _ExAllocatePool
|
||||||
|
U _ExFreePool
|
||||||
|
U _IoAttachDeviceToDeviceStack
|
||||||
|
U _IoBuildSynchronousFsdRequest
|
||||||
|
U _IoCallDriver
|
||||||
|
U _IoCompleteRequest
|
||||||
|
U _IoCreateDevice
|
||||||
|
U _IoGetCurrentIrpStackLocation
|
||||||
|
U _IoRegisterFileSystem
|
||||||
|
U _KeInitializeEvent
|
||||||
|
U _KeWaitForSingleObject
|
||||||
|
U _MmGetSystemAddressForMdl
|
||||||
|
U _RtlAnsiStringToUnicodeString
|
||||||
|
U _RtlCopyMemory
|
||||||
|
U _RtlInitAnsiString
|
||||||
|
U _wcschr
|
||||||
|
00000000 t .text
|
||||||
|
00000000 t LC0
|
||||||
|
00000000 t ___gnu_compiled_c
|
||||||
|
00000000 t gcc2_compiled.
|
||||||
|
00000008 t LC1
|
||||||
|
00000011 t LC2
|
||||||
|
00000022 T _MinixCheckPoint
|
||||||
|
0000004b t LC3
|
||||||
|
0000006c t _MinixGetBlock
|
||||||
|
000000b0 t L147
|
||||||
|
0000010a t L148
|
||||||
|
00000124 t L151
|
||||||
|
0000012b t L150
|
||||||
|
00000135 t LC4
|
||||||
|
00000143 t LC5
|
||||||
|
0000014d t LC6
|
||||||
|
00000155 t LC7
|
||||||
|
0000015d t LC8
|
||||||
|
00000196 T _MinixReadBlock
|
||||||
|
0000029c t .text
|
||||||
|
0000029c t LC0
|
||||||
|
0000029c t ___gnu_compiled_c
|
||||||
|
0000029c t gcc2_compiled.
|
||||||
|
000002a1 t LC1
|
||||||
|
000002aa t LC2
|
||||||
|
000002ce T _MinixWrite
|
||||||
|
00000319 t LC3
|
||||||
|
0000033d t LC4
|
||||||
|
0000035c t LC5
|
||||||
|
00000363 t LC6
|
||||||
|
00000388 t LC7
|
||||||
|
00000393 t LC8
|
||||||
|
000003ba T _MinixRead
|
||||||
|
00000492 t L151
|
||||||
|
000004a2 t L152
|
||||||
|
00000508 t L181
|
||||||
|
0000059e t L191
|
||||||
|
000005d1 t L153
|
||||||
|
000005d6 t L199
|
||||||
|
00000635 t L257
|
||||||
|
000006a1 t L228
|
||||||
|
000006bb t L256
|
||||||
|
000006c4 t .text
|
||||||
|
000006c4 T _MinixDeleteInode
|
||||||
|
000006c4 t ___gnu_compiled_c
|
||||||
|
000006c4 t gcc2_compiled.
|
||||||
|
0000071a t _MinixAllocateInode
|
||||||
|
00000778 t L167
|
||||||
|
000007c2 t L166
|
||||||
|
000007de t L165
|
||||||
|
000007e6 t L173
|
||||||
|
000007ee T _MinixNewInode
|
||||||
|
0000081a t L175
|
||||||
|
0000081c t L176
|
||||||
|
00000824 T _MinixWriteInode
|
||||||
|
000008a2 T _MinixReadInode
|
||||||
|
0000090c t .text
|
||||||
|
0000090c T _MinixCompareUnicodeStringToAnsi
|
||||||
|
0000090c t ___gnu_compiled_c
|
||||||
|
0000090c t gcc2_compiled.
|
||||||
|
00000920 t L140
|
||||||
|
00000936 t L141
|
||||||
|
0000093f t L142
|
||||||
|
0000094b t L139
|
||||||
|
00000950 t L144
|
||||||
|
00000958 t LC0
|
||||||
|
0000095e t LC1
|
||||||
|
00000967 t LC2
|
||||||
|
00000996 t LC3
|
||||||
|
0000099d t LC4
|
||||||
|
000009b2 t LC5
|
||||||
|
000009ca T _MinixDirLookup
|
||||||
|
00000a26 t L153
|
||||||
|
00000aa3 t L163
|
||||||
|
00000ad8 t L158
|
||||||
|
00000b68 t L152
|
||||||
|
00000b80 t L151
|
||||||
|
00000bb6 t L186
|
||||||
|
00000bde t L191
|
||||||
|
00000be6 t LC6
|
||||||
|
00000c1c t LC7
|
||||||
|
00000c2b t LC8
|
||||||
|
00000c3f t LC9
|
||||||
|
00000c5c T _MinixOpen
|
||||||
|
00000cc0 t L206
|
||||||
|
00000d26 t L205
|
||||||
|
00000d3d t L198
|
||||||
|
00000d43 t L237
|
||||||
|
00000d5c t L207
|
||||||
|
00000d6c t L208
|
||||||
|
00000da7 t L236
|
||||||
|
00000daf t LC10
|
||||||
|
00000dd4 T _MinixClose
|
||||||
|
00000e40 t LC11
|
||||||
|
00000e66 t LC12
|
||||||
|
00000e7a t LC13
|
||||||
|
00000e9a t LC14
|
||||||
|
00000ea6 T _MinixCreate
|
||||||
|
00000fa7 t L260
|
||||||
|
00000fc8 t .text
|
||||||
|
00000fc8 T _MinixMount
|
||||||
|
00000fc8 t ___gnu_compiled_c
|
||||||
|
00000fc8 t gcc2_compiled.
|
||||||
|
0000103b t LC0
|
||||||
|
0000106c T _MinixFileSystemControl
|
||||||
|
000010bc t L139
|
||||||
|
000010c1 t L140
|
||||||
|
000010e2 t LC1
|
||||||
|
000010f3 t LC2
|
||||||
|
00001102 T _DriverEntry
|
||||||
|
000011b1 t L142
|
||||||
|
000011b8 t .text
|
||||||
|
000011b8 T _MinixReadSector
|
||||||
|
000011b8 t ___gnu_compiled_c
|
||||||
|
000011b8 t gcc2_compiled.
|
||||||
|
00001232 t L140
|
||||||
|
00001252 t L141
|
||||||
|
00001258 t L143
|
||||||
|
0000125a t L142
|
||||||
|
00001262 T _MinixWriteSector
|
||||||
|
000012c3 t L145
|
||||||
|
000012ce t L146
|
||||||
|
000012d0 t L147
|
||||||
|
00002000 b .bss
|
||||||
|
00002000 b .bss
|
||||||
|
00002000 b .bss
|
||||||
|
00002000 b .bss
|
||||||
|
00002000 b .bss
|
||||||
|
00002000 d .data
|
||||||
|
00002000 d .data
|
||||||
|
00002000 d .data
|
||||||
|
00002000 d .data
|
||||||
|
00002000 d .data
|
||||||
|
00002000 d .data
|
||||||
|
00002000 b _DriverObject
|
||||||
|
00002004 b .bss
|
133
reactos/drivers/fs/minix/mount.c
Normal file
133
reactos/drivers/fs/minix/mount.c
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/fs/minix/minix.c
|
||||||
|
* PURPOSE: Minix FSD
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <ddk/ntifs.h>
|
||||||
|
#include <internal/string.h>
|
||||||
|
#include <wstring.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
#include "minix.h"
|
||||||
|
|
||||||
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
static PDRIVER_OBJECT DriverObject;
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
VOID MinixMount(PDEVICE_OBJECT DeviceToMount)
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt;
|
||||||
|
|
||||||
|
IoCreateDevice(DriverObject,
|
||||||
|
sizeof(MINIX_DEVICE_EXTENSION),
|
||||||
|
NULL,
|
||||||
|
FILE_DEVICE_FILE_SYSTEM,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
&DeviceObject);
|
||||||
|
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
|
||||||
|
DeviceExt = DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
MinixReadSector(DeviceToMount,1,DeviceExt->superblock_buf);
|
||||||
|
DeviceExt->sb = (struct minix_super_block *)(DeviceExt->superblock_buf);
|
||||||
|
|
||||||
|
DeviceExt->AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject,
|
||||||
|
DeviceToMount);
|
||||||
|
CbInitDccb(&DeviceExt->Dccb,DeviceExt->AttachedDevice,
|
||||||
|
BLOCKSIZE,2880,10);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS MinixFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PVPB vpb = Stack->Parameters.Mount.Vpb;
|
||||||
|
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
|
||||||
|
NTSTATUS Status;
|
||||||
|
char* superblock_buf;
|
||||||
|
struct minix_super_block* sb;
|
||||||
|
|
||||||
|
DbgPrint("MinixFileSystemControl(DeviceObject %x, Irp %x)\n",DeviceObject,
|
||||||
|
Irp);
|
||||||
|
DPRINT("DeviceToMount %x\n",DeviceToMount);
|
||||||
|
|
||||||
|
superblock_buf = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||||
|
|
||||||
|
DPRINT("MinixReadSector %x\n",MinixReadSector);
|
||||||
|
MinixReadSector(DeviceToMount,1,superblock_buf);
|
||||||
|
sb = (struct minix_super_block *)superblock_buf;
|
||||||
|
DPRINT("Magic %x\n",sb->s_magic);
|
||||||
|
DPRINT("Imap blocks %x\n",sb->s_imap_blocks);
|
||||||
|
DPRINT("Zmap blocks %x\n",sb->s_zmap_blocks);
|
||||||
|
if (sb->s_magic==MINIX_SUPER_MAGIC2)
|
||||||
|
{
|
||||||
|
DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__);
|
||||||
|
MinixMount(DeviceToMount);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("%s() = STATUS_UNRECOGNIZED_VOLUME\n",__FUNCTION__);
|
||||||
|
Status = STATUS_UNRECOGNIZED_VOLUME;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
|
PUNICODE_STRING RegistryPath)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Called by the system to initalize the driver
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DriverObject = object describing this driver
|
||||||
|
* RegistryPath = path to our configuration entries
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
NTSTATUS ret;
|
||||||
|
UNICODE_STRING ustr;
|
||||||
|
ANSI_STRING astr;
|
||||||
|
|
||||||
|
DbgPrint("Minix FSD 0.0.1\n");
|
||||||
|
|
||||||
|
DriverObject = _DriverObject;
|
||||||
|
|
||||||
|
RtlInitAnsiString(&astr,"\\Device\\Minix");
|
||||||
|
RtlAnsiStringToUnicodeString(&ustr,&astr,TRUE);
|
||||||
|
ret = IoCreateDevice(DriverObject,0,&ustr,
|
||||||
|
FILE_DEVICE_PARALLEL_PORT,0,FALSE,&DeviceObject);
|
||||||
|
if (ret!=STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceObject->Flags=0;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MinixClose;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = MinixCreate;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_READ] = MinixRead;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = MinixWrite;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
||||||
|
MinixFileSystemControl;
|
||||||
|
DriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
|
IoRegisterFileSystem(DeviceObject);
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
117
reactos/drivers/fs/minix/rw.c
Normal file
117
reactos/drivers/fs/minix/rw.c
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/fs/minix/rw.c
|
||||||
|
* PURPOSE: Minix FSD
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/string.h>
|
||||||
|
#include <wstring.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
#include "minix.h"
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS MinixWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
DPRINT("MinixWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS MinixRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
ULONG Length;
|
||||||
|
PVOID Buffer;
|
||||||
|
ULONG Offset;
|
||||||
|
ULONG CurrentOffset;
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
|
MINIX_DEVICE_EXTENSION* DeviceExt = DeviceObject->DeviceExtension;
|
||||||
|
struct minix_inode* inode = (struct minix_inode *)FileObject->FsContext;
|
||||||
|
unsigned int i;
|
||||||
|
PCCB Ccb = NULL;
|
||||||
|
|
||||||
|
DPRINT("MinixRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
||||||
|
|
||||||
|
Length = Stack->Parameters.Read.Length;
|
||||||
|
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||||
|
Offset = Stack->Parameters.Read.ByteOffset.LowPart;
|
||||||
|
|
||||||
|
DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
|
||||||
|
|
||||||
|
CurrentOffset=Offset;
|
||||||
|
|
||||||
|
DPRINT("inode->i_size %d\n",inode->i_size);
|
||||||
|
|
||||||
|
if (Offset > inode->i_size)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
if ((Offset+Length) > inode->i_size)
|
||||||
|
{
|
||||||
|
Length = inode->i_size - Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Offset%BLOCKSIZE)!=0)
|
||||||
|
{
|
||||||
|
CHECKPOINT;
|
||||||
|
|
||||||
|
CurrentOffset = Offset - (Offset%BLOCKSIZE);
|
||||||
|
|
||||||
|
MinixReadBlock(DeviceExt,inode,
|
||||||
|
CurrentOffset/BLOCKSIZE,
|
||||||
|
&Ccb);
|
||||||
|
memcpy(Buffer,Ccb->Buffer+(Offset%BLOCKSIZE),
|
||||||
|
min(BLOCKSIZE - (Offset%BLOCKSIZE),Length));
|
||||||
|
DPRINT("(BLOCKSIZE - (Offset%BLOCKSIZE)) %d\n",
|
||||||
|
(BLOCKSIZE - (Offset%BLOCKSIZE)));
|
||||||
|
DPRINT("Length %d\n",Length);
|
||||||
|
CurrentOffset = CurrentOffset + BLOCKSIZE;
|
||||||
|
Buffer = Buffer + BLOCKSIZE - (Offset%BLOCKSIZE);
|
||||||
|
Length = Length - min(BLOCKSIZE - (Offset%BLOCKSIZE),Length);
|
||||||
|
DPRINT("CurrentOffset %d Buffer %x Length %d\n",CurrentOffset,Buffer,
|
||||||
|
Length);
|
||||||
|
}
|
||||||
|
for (i=0;i<(Length/BLOCKSIZE);i++)
|
||||||
|
{
|
||||||
|
CHECKPOINT;
|
||||||
|
|
||||||
|
DPRINT("Length %d\n",Length);
|
||||||
|
|
||||||
|
MinixReadBlock(DeviceExt,inode,
|
||||||
|
CurrentOffset/BLOCKSIZE,&Ccb);
|
||||||
|
memcpy(Buffer,Ccb->Buffer,BLOCKSIZE);
|
||||||
|
CurrentOffset = CurrentOffset + BLOCKSIZE;
|
||||||
|
Buffer = Buffer + BLOCKSIZE;
|
||||||
|
}
|
||||||
|
if ((Length%BLOCKSIZE) > 0)
|
||||||
|
{
|
||||||
|
CHECKPOINT;
|
||||||
|
|
||||||
|
DPRINT("Length %x Buffer %x\n",(Length%BLOCKSIZE),Buffer);
|
||||||
|
|
||||||
|
MinixReadBlock(DeviceExt,inode,
|
||||||
|
CurrentOffset/BLOCKSIZE,
|
||||||
|
&Ccb);
|
||||||
|
memcpy(Buffer,Ccb->Buffer,(Length%BLOCKSIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = Length;
|
||||||
|
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
2
reactos/drivers/fs/template/makefile
Normal file
2
reactos/drivers/fs/template/makefile
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
all: template.o
|
||||||
|
$(LD) -r template.o -o tfsd.o
|
225
reactos/drivers/fs/template/template.c
Normal file
225
reactos/drivers/fs/template/template.c
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/fs/template/template.c
|
||||||
|
* PURPOSE: Bare filesystem template
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/string.h>
|
||||||
|
#include <wstring.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT StorageDevice;
|
||||||
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||||
|
|
||||||
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
||||||
|
static PDRIVER_OBJECT DriverObject;
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Closes a file
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
PWSTR FileName)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Opens a file
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Tests if the device contains a filesystem that can be mounted
|
||||||
|
* by this fsd
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
PDEVICE_OBJECT DeviceToMount)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Mounts the device
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
PVOID Buffer, ULONG Length, ULONG Offset)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Reads data from a file
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
|
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = FsdCloseFile(DeviceExtension,FileObject);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PDEVICE_EXTENSION DeviceExt;
|
||||||
|
|
||||||
|
DeviceExt = DeviceObject->DeviceExtension;
|
||||||
|
Status = FsdOpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
ULONG Length;
|
||||||
|
PVOID Buffer;
|
||||||
|
ULONG Offset;
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
|
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
||||||
|
|
||||||
|
Length = Stack->Parameters.Read.Length;
|
||||||
|
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||||
|
Offset = Stack->Parameters.Read.ByteOffset.LowPart;
|
||||||
|
|
||||||
|
Status = FsdReadFile(DeviceExt,FileObject,Buffer,Length,Offset);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = Length;
|
||||||
|
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PDEVICE_EXTENSION DeviceExt;
|
||||||
|
|
||||||
|
IoCreateDevice(DriverObject,
|
||||||
|
sizeof(DEVICE_EXTENSION),
|
||||||
|
NULL,
|
||||||
|
FILE_DEVICE_FILE_SYSTEM,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
&DeviceObject);
|
||||||
|
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
|
||||||
|
DeviceExt = (PVOID)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
FsdMountDevice(DeviceExt,DeviceToMount);
|
||||||
|
|
||||||
|
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
|
||||||
|
DeviceToMount);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PVPB vpb = Stack->Parameters.Mount.Vpb;
|
||||||
|
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (FsdHasFileSystem(DeviceToMount))
|
||||||
|
{
|
||||||
|
Status = FsdMount(DeviceToMount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_UNRECOGNIZED_VOLUME;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
|
PUNICODE_STRING RegistryPath)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Called by the system to initalize the driver
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DriverObject = object describing this driver
|
||||||
|
* RegistryPath = path to our configuration entries
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
NTSTATUS ret;
|
||||||
|
UNICODE_STRING ustr;
|
||||||
|
ANSI_STRING astr;
|
||||||
|
|
||||||
|
DbgPrint("Bare FSD Template 0.0.1\n");
|
||||||
|
|
||||||
|
DriverObject = _DriverObject;
|
||||||
|
|
||||||
|
RtlInitAnsiString(&astr,"\\Device\\BareFsd");
|
||||||
|
RtlAnsiStringToUnicodeString(&ustr,&astr,TRUE);
|
||||||
|
ret = IoCreateDevice(DriverObject,0,&ustr,
|
||||||
|
FILE_DEVICE_FILE_SYSTEM,0,FALSE,&DeviceObject);
|
||||||
|
if (ret!=STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceObject->Flags=0;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_READ] = FsdRead;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
||||||
|
FsdFileSystemControl;
|
||||||
|
DriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
|
IoRegisterFileSystem(DeviceObject);
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
89
reactos/drivers/fs/vfat/blockdev.c
Normal file
89
reactos/drivers/fs/vfat/blockdev.c
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/fs/vfat/blockdev.c
|
||||||
|
* PURPOSE: Temporary sector reading support
|
||||||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/string.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
#include "vfat.h"
|
||||||
|
|
||||||
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
|
BOOLEAN VFATReadSector(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
|
IN ULONG DiskSector,
|
||||||
|
IN UCHAR* Buffer)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER sectorNumber;
|
||||||
|
PIRP irp;
|
||||||
|
IO_STATUS_BLOCK ioStatus;
|
||||||
|
KEVENT event;
|
||||||
|
NTSTATUS status;
|
||||||
|
ULONG sectorSize;
|
||||||
|
PULONG mbr;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
DPRINT("VFATReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
||||||
|
pDeviceObject,DiskSector,Buffer);
|
||||||
|
|
||||||
|
sectorNumber.HighPart = 0;
|
||||||
|
sectorNumber.LowPart = DiskSector * BLOCKSIZE;
|
||||||
|
|
||||||
|
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
sectorSize = BLOCKSIZE;
|
||||||
|
|
||||||
|
mbr = ExAllocatePool(NonPagedPool, sectorSize);
|
||||||
|
|
||||||
|
if (!mbr) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
||||||
|
pDeviceObject,
|
||||||
|
mbr,
|
||||||
|
sectorSize,
|
||||||
|
§orNumber,
|
||||||
|
&event,
|
||||||
|
&ioStatus );
|
||||||
|
|
||||||
|
if (!irp) {
|
||||||
|
DbgPrint("READ failed!!!\n");
|
||||||
|
ExFreePool(mbr);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = IoCallDriver(pDeviceObject,
|
||||||
|
irp);
|
||||||
|
|
||||||
|
if (status == STATUS_PENDING) {
|
||||||
|
KeWaitForSingleObject(&event,
|
||||||
|
Suspended,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
|
status = ioStatus.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
DbgPrint("IO failed!!! Error code: %d\n", status);
|
||||||
|
ExFreePool(mbr);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlCopyMemory(Buffer,mbr,sectorSize);
|
||||||
|
|
||||||
|
ExFreePool(mbr);
|
||||||
|
DPRINT("Block request succeeded\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
743
reactos/drivers/fs/vfat/iface.c
Normal file
743
reactos/drivers/fs/vfat/iface.c
Normal file
|
@ -0,0 +1,743 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: services/fs/vfat/iface.c
|
||||||
|
* PURPOSE: VFAT Filesystem
|
||||||
|
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/string.h>
|
||||||
|
#include <wstring.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
#include "vfat.h"
|
||||||
|
|
||||||
|
#define FAT16 (1)
|
||||||
|
#define FAT12 (2)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT StorageDevice;
|
||||||
|
BootSector *Boot;
|
||||||
|
int rootDirectorySectors, FATStart, rootStart, dataStart;
|
||||||
|
int FATEntriesPerSector, FATUnit;
|
||||||
|
ULONG BytesPerCluster;
|
||||||
|
ULONG FatType;
|
||||||
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FATDirEntry entry;
|
||||||
|
} FCB, *PFCB;
|
||||||
|
|
||||||
|
#define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
|
||||||
|
|
||||||
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
||||||
|
static PDRIVER_OBJECT DriverObject;
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
|
{
|
||||||
|
ULONG FATsector;
|
||||||
|
ULONG FATeis;
|
||||||
|
PUSHORT Block;
|
||||||
|
|
||||||
|
Block = ExAllocatePool(NonPagedPool,1024);
|
||||||
|
|
||||||
|
FATsector=CurrentCluster/(512/sizeof(USHORT));
|
||||||
|
FATeis=CurrentCluster-(FATsector*256);
|
||||||
|
|
||||||
|
DPRINT("FATsector %d FATeis %d\n",FATsector,FATeis);
|
||||||
|
DPRINT("DeviceExt->FATStart %d\n",DeviceExt->FATStart);
|
||||||
|
|
||||||
|
VFATReadSector(DeviceExt->StorageDevice,DeviceExt->FATStart+FATsector,
|
||||||
|
Block);
|
||||||
|
|
||||||
|
DPRINT("offset %x\n",(&Block[FATeis])-Block);
|
||||||
|
|
||||||
|
CurrentCluster = Block[FATeis];
|
||||||
|
|
||||||
|
DPRINT("CurrentCluster %x\n",CurrentCluster);
|
||||||
|
|
||||||
|
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
|
||||||
|
{
|
||||||
|
CurrentCluster = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExFreePool(Block);
|
||||||
|
|
||||||
|
DPRINT("Returning %x\n",CurrentCluster);
|
||||||
|
|
||||||
|
return(CurrentCluster);
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
|
{
|
||||||
|
unsigned char* CBlock;
|
||||||
|
ULONG FATsector;
|
||||||
|
ULONG FATOffset;
|
||||||
|
ULONG Entry;
|
||||||
|
|
||||||
|
CBlock = ExAllocatePool(NonPagedPool,1024);
|
||||||
|
|
||||||
|
FATsector = (CurrentCluster * 12) / (512 * 8);
|
||||||
|
|
||||||
|
VFATReadSector(DeviceExt->StorageDevice,DeviceExt->FATStart
|
||||||
|
+FATsector,CBlock);
|
||||||
|
|
||||||
|
FATOffset = (CurrentCluster * 12) % (512 * 8);
|
||||||
|
|
||||||
|
// DPRINT("FATSector %d FATOffset %d\n",FATsector,FATOffset);
|
||||||
|
|
||||||
|
if ((CurrentCluster % 2) == 0)
|
||||||
|
{
|
||||||
|
Entry = CBlock[((FATOffset / 24)*3)];
|
||||||
|
Entry |= (CBlock[((FATOffset / 24)*3) + 1] & 0xf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Entry = (CBlock[((FATOffset / 24)*3) + 1] >> 4);
|
||||||
|
Entry |= (CBlock[((FATOffset / 24)*3) + 2] << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DPRINT("Entry %x\n",Entry);
|
||||||
|
|
||||||
|
if (Entry >= 0xff8 && Entry <= 0xfff)
|
||||||
|
{
|
||||||
|
Entry = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentCluster = Entry;
|
||||||
|
|
||||||
|
ExFreePool(CBlock);
|
||||||
|
|
||||||
|
DPRINT("Returning %x\n",CurrentCluster);
|
||||||
|
|
||||||
|
return(CurrentCluster);
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
|
{
|
||||||
|
|
||||||
|
DPRINT("GetNextCluster(DeviceExt %x, CurrentCluster %d)\n",
|
||||||
|
DeviceExt,CurrentCluster);
|
||||||
|
if (DeviceExt->FatType == FAT16)
|
||||||
|
{
|
||||||
|
return(Fat16GetNextCluster(DeviceExt, CurrentCluster));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(Fat12GetNextCluster(DeviceExt, CurrentCluster));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long ClusterToSector(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
unsigned long Cluster)
|
||||||
|
{
|
||||||
|
return DeviceExt->dataStart+((Cluster-2)*DeviceExt->Boot->SectorsPerCluster);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; (i<Length && Source[i] != ' '); i++)
|
||||||
|
{
|
||||||
|
Dest[i] = Source[i];
|
||||||
|
}
|
||||||
|
Dest[i]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtlCatAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
while((*Dest)!=0)
|
||||||
|
{
|
||||||
|
Dest++;
|
||||||
|
}
|
||||||
|
for (i=0; (i<Length && Source[i] != ' '); i++)
|
||||||
|
{
|
||||||
|
Dest[i] = Source[i];
|
||||||
|
}
|
||||||
|
Dest[i]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t * wcsncat(wchar_t * dest,const wchar_t * src,size_t count)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
|
||||||
|
for (j=0;dest[j]!=0;j++);
|
||||||
|
for (i=0;i<count;i++)
|
||||||
|
{
|
||||||
|
dest[j+i] = src[i];
|
||||||
|
if (src[i] == ' ' || src[i] == 0)
|
||||||
|
{
|
||||||
|
return(dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dest[j+i]=0;
|
||||||
|
return(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
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] == ' ' || src[i] == 0)
|
||||||
|
{
|
||||||
|
return(dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dest[i]=0;
|
||||||
|
return(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOLEAN IsLastEntry(PVOID Block, ULONG Offset)
|
||||||
|
{
|
||||||
|
return(((FATDirEntry *)Block)[Offset].Filename[0] == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset)
|
||||||
|
{
|
||||||
|
return(((FATDirEntry *)Block)[Offset].Filename[0] == 0xe5);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN GetEntryName(PVOID Block, PULONG _Offset, PWSTR Name)
|
||||||
|
{
|
||||||
|
FATDirEntry* test;
|
||||||
|
slot* test2;
|
||||||
|
ULONG Offset = *_Offset;
|
||||||
|
|
||||||
|
test = (FATDirEntry *)Block;
|
||||||
|
test2 = (slot *)Block;
|
||||||
|
|
||||||
|
*Name = 0;
|
||||||
|
|
||||||
|
if (IsDeletedEntry(Block,Offset))
|
||||||
|
{
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("Offset %d test2[Offset].attr %x\n",Offset,test2[Offset].attr);
|
||||||
|
if(test2[Offset].attr == 0x0f)
|
||||||
|
{
|
||||||
|
DPRINT("Parsing long name record\n");
|
||||||
|
wcsncpy(Name,test2[Offset].name0_4,5);
|
||||||
|
DPRINT("Name %w\n",Name);
|
||||||
|
wcsncat(Name,test2[Offset].name5_10,6);
|
||||||
|
DPRINT("Name %w\n",Name);
|
||||||
|
wcsncat(Name,test2[Offset].name11_12,2);
|
||||||
|
DPRINT("Name %w\n",Name);
|
||||||
|
|
||||||
|
while((test2[Offset].id!=0x41) && (test2[Offset].id!=0x01) &&
|
||||||
|
(test2[Offset].attr>0))
|
||||||
|
{
|
||||||
|
Offset++;
|
||||||
|
|
||||||
|
DPRINT("Reading next long name record\n");
|
||||||
|
|
||||||
|
wcsncat(Name,test2[Offset].name0_4,5);
|
||||||
|
wcsncat(Name,test2[Offset].name5_10,6);
|
||||||
|
wcsncat(Name,test2[Offset].name11_12,2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsDeletedEntry(Block,Offset+1))
|
||||||
|
{
|
||||||
|
Offset++;
|
||||||
|
*_Offset = Offset;
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
*_Offset = Offset;
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlAnsiToUnicode(Name,test[Offset].Filename,8);
|
||||||
|
if (test[Offset].Ext[0]!=' ')
|
||||||
|
{
|
||||||
|
RtlCatAnsiToUnicode(Name,".",1);
|
||||||
|
}
|
||||||
|
RtlCatAnsiToUnicode(Name,test[Offset].Ext,3);
|
||||||
|
|
||||||
|
*_Offset = Offset;
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN wstrcmpi(PWSTR s1, PWSTR s2)
|
||||||
|
{
|
||||||
|
DPRINT("s1 '%w' s2 '%w'\n",s1,s2);
|
||||||
|
while (wtolower(*s1)==wtolower(*s2))
|
||||||
|
{
|
||||||
|
if ((*s1)==0 && (*s2)==0)
|
||||||
|
{
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
}
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||||
|
PFCB Parent, PWSTR FileToFind)
|
||||||
|
{
|
||||||
|
ULONG i, j, k;
|
||||||
|
ULONG Size;
|
||||||
|
char* block;
|
||||||
|
WCHAR name[255];
|
||||||
|
ULONG StartingSector;
|
||||||
|
ULONG NextCluster;
|
||||||
|
|
||||||
|
DPRINT("FileFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
|
||||||
|
|
||||||
|
if (Parent == NULL)
|
||||||
|
{
|
||||||
|
Size = DeviceExt->rootDirectorySectors;
|
||||||
|
StartingSector = DeviceExt->rootStart;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Parent->entry.FileSize %x\n",Parent->entry.FileSize);
|
||||||
|
|
||||||
|
Size = ULONG_MAX;
|
||||||
|
StartingSector = ClusterToSector(DeviceExt, Parent->entry.FirstCluster);
|
||||||
|
NextCluster = Parent->entry.FirstCluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||||
|
|
||||||
|
for (j=0; j<Size; j++)
|
||||||
|
{
|
||||||
|
VFATReadSector(DeviceExt->StorageDevice,StartingSector,block);
|
||||||
|
|
||||||
|
|
||||||
|
DPRINT("%u\n", StartingSector+j);
|
||||||
|
|
||||||
|
for (i=0; i<ENTRIES_PER_SECTOR; i++)
|
||||||
|
{
|
||||||
|
if (IsLastEntry((PVOID)block,i))
|
||||||
|
{
|
||||||
|
ExFreePool(block);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
if (GetEntryName((PVOID)block,&i,name))
|
||||||
|
{
|
||||||
|
DPRINT("Scanning %w\n",name);
|
||||||
|
|
||||||
|
DPRINT("Comparing %w %w\n",name,FileToFind);
|
||||||
|
if (wstrcmpi(name,FileToFind))
|
||||||
|
{
|
||||||
|
DPRINT("Found match\n");
|
||||||
|
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
|
||||||
|
sizeof(FATDirEntry));
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (Parent == NULL)
|
||||||
|
{
|
||||||
|
StartingSector++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NextCluster = GetNextCluster(DeviceExt,NextCluster);
|
||||||
|
if (NextCluster == 0)
|
||||||
|
{
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
StartingSector = ClusterToSector(DeviceExt,NextCluster);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExFreePool(block);
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Closes a file
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* NOP */
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
PWSTR FileName)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Opens a file
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PWSTR current;
|
||||||
|
PWSTR next;
|
||||||
|
PWSTR string = FileName;
|
||||||
|
PFCB ParentFcb = NULL;
|
||||||
|
PFCB Fcb = ExAllocatePool(NonPagedPool,sizeof(FCB));
|
||||||
|
PFCB Temp;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
next = &string[0];
|
||||||
|
current = next+1;
|
||||||
|
|
||||||
|
while (next!=NULL)
|
||||||
|
{
|
||||||
|
DPRINT("current %w next %x\n",current,next);
|
||||||
|
|
||||||
|
*next = '\\';
|
||||||
|
current = next+1;
|
||||||
|
next = wcschr(next+1,'\\');
|
||||||
|
if (next!=NULL)
|
||||||
|
{
|
||||||
|
*next=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FindFile(DeviceExt,Fcb,ParentFcb,current);
|
||||||
|
if (Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
Temp = Fcb;
|
||||||
|
if (ParentFcb == NULL)
|
||||||
|
{
|
||||||
|
Fcb = ExAllocatePool(NonPagedPool,sizeof(FCB));
|
||||||
|
ParentFcb = Temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fcb = ParentFcb;
|
||||||
|
ParentFcb = Temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FileObject->FsContext = ParentFcb;
|
||||||
|
DPRINT("ParentFcb->entry.FileSize %d\n",ParentFcb->entry.FileSize);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Tests if the device contains a filesystem that can be mounted
|
||||||
|
* by this fsd
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
BootSector* Boot;
|
||||||
|
|
||||||
|
Boot = ExAllocatePool(NonPagedPool,512);
|
||||||
|
VFATReadSector(DeviceToMount, 0, (UCHAR *)Boot);
|
||||||
|
|
||||||
|
if (strncmp(Boot->SysType,"FAT12",5)==0 ||
|
||||||
|
strncmp(Boot->SysType,"FAT16",5)==0)
|
||||||
|
{
|
||||||
|
ExFreePool(Boot);
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
ExFreePool(Boot);
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
PDEVICE_OBJECT DeviceToMount)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Mounts the device
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
DPRINT("<VFAT> Mounting device...");
|
||||||
|
DPRINT("DeviceExt %x\n",DeviceExt);
|
||||||
|
|
||||||
|
DeviceExt->Boot = ExAllocatePool(NonPagedPool,512);
|
||||||
|
|
||||||
|
VFATReadSector(DeviceToMount, 0, (UCHAR *)DeviceExt->Boot);
|
||||||
|
|
||||||
|
DPRINT("DeviceExt->Boot->BytesPerSector %x\n",
|
||||||
|
DeviceExt->Boot->BytesPerSector);
|
||||||
|
|
||||||
|
DeviceExt->FATStart=DeviceExt->Boot->ReservedSectors;
|
||||||
|
DeviceExt->rootDirectorySectors=
|
||||||
|
(DeviceExt->Boot->RootEntries*32)/DeviceExt->Boot->BytesPerSector;
|
||||||
|
DeviceExt->rootStart=
|
||||||
|
DeviceExt->FATStart+DeviceExt->Boot->FATCount*DeviceExt->Boot->FATSectors;
|
||||||
|
DeviceExt->dataStart=DeviceExt->rootStart+DeviceExt->rootDirectorySectors;
|
||||||
|
DeviceExt->FATEntriesPerSector=DeviceExt->Boot->BytesPerSector/32;
|
||||||
|
DeviceExt->BytesPerCluster = DeviceExt->Boot->SectorsPerCluster *
|
||||||
|
DeviceExt->Boot->BytesPerSector;
|
||||||
|
|
||||||
|
if (strncmp(DeviceExt->Boot->SysType,"FAT12",5)==0)
|
||||||
|
{
|
||||||
|
DeviceExt->FatType = FAT12;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DeviceExt->FatType = FAT16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
||||||
|
{
|
||||||
|
ULONG Sector;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
// DPRINT("VFATLoadCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
||||||
|
// DeviceExt,Buffer,Cluster);
|
||||||
|
|
||||||
|
Sector = ClusterToSector(DeviceExt, Cluster);
|
||||||
|
|
||||||
|
for (i=0; i<DeviceExt->Boot->SectorsPerCluster; i++)
|
||||||
|
{
|
||||||
|
VFATReadSector(DeviceExt->StorageDevice,
|
||||||
|
Sector+i,
|
||||||
|
Buffer+(i*DeviceExt->Boot->BytesPerSector));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
PVOID Buffer, ULONG Length, ULONG ReadOffset)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Reads data from a file
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ULONG CurrentCluster;
|
||||||
|
ULONG FileOffset;
|
||||||
|
ULONG i;
|
||||||
|
ULONG FirstCluster;
|
||||||
|
PFCB Fcb;
|
||||||
|
PVOID Temp;
|
||||||
|
ULONG TempLength;
|
||||||
|
|
||||||
|
DPRINT("FsdReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
|
||||||
|
"Length %d, ReadOffset %d)\n",DeviceExt,FileObject,Buffer,
|
||||||
|
Length,ReadOffset);
|
||||||
|
|
||||||
|
FirstCluster = ReadOffset / DeviceExt->BytesPerCluster;
|
||||||
|
Fcb = FileObject->FsContext;
|
||||||
|
CurrentCluster = Fcb->entry.FirstCluster;
|
||||||
|
|
||||||
|
DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster);
|
||||||
|
DPRINT("FirstCluster %d\n",FirstCluster);
|
||||||
|
DPRINT("CurrentCluster %d\n",CurrentCluster);
|
||||||
|
|
||||||
|
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
||||||
|
|
||||||
|
for (FileOffset=0; FileOffset < FirstCluster; FileOffset++)
|
||||||
|
{
|
||||||
|
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
||||||
|
if (CurrentCluster == 0)
|
||||||
|
{
|
||||||
|
ExFreePool(Temp);
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CHECKPOINT;
|
||||||
|
if ((ReadOffset % DeviceExt->BytesPerCluster)!=0)
|
||||||
|
{
|
||||||
|
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
||||||
|
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
||||||
|
|
||||||
|
TempLength = min(Length,DeviceExt->BytesPerCluster -
|
||||||
|
(ReadOffset % DeviceExt->BytesPerCluster));
|
||||||
|
|
||||||
|
memcpy(Buffer, Temp + ReadOffset % DeviceExt->BytesPerCluster,
|
||||||
|
TempLength);
|
||||||
|
|
||||||
|
Length = Length - TempLength;
|
||||||
|
Buffer = Buffer + TempLength;
|
||||||
|
}
|
||||||
|
CHECKPOINT;
|
||||||
|
while (Length > DeviceExt->BytesPerCluster)
|
||||||
|
{
|
||||||
|
VFATLoadCluster(DeviceExt, Buffer, CurrentCluster);
|
||||||
|
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
||||||
|
|
||||||
|
if (CurrentCluster == 0)
|
||||||
|
{
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer = Buffer + DeviceExt->BytesPerCluster;
|
||||||
|
Length = Length - DeviceExt->BytesPerCluster;
|
||||||
|
}
|
||||||
|
CHECKPOINT;
|
||||||
|
if (Length > 0)
|
||||||
|
{
|
||||||
|
VFATLoadCluster(DeviceExt, Temp, CurrentCluster);
|
||||||
|
memcpy(Buffer, Temp, Length);
|
||||||
|
}
|
||||||
|
ExFreePool(Temp);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
|
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = FsdCloseFile(DeviceExtension,FileObject);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PDEVICE_EXTENSION DeviceExt;
|
||||||
|
|
||||||
|
DPRINT("<VFAT> FsdCreate...\n");
|
||||||
|
|
||||||
|
DeviceExt = DeviceObject->DeviceExtension;
|
||||||
|
Status = FsdOpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
ULONG Length;
|
||||||
|
PVOID Buffer;
|
||||||
|
ULONG Offset;
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
|
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
||||||
|
|
||||||
|
Length = Stack->Parameters.Read.Length;
|
||||||
|
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||||
|
Offset = Stack->Parameters.Read.ByteOffset.LowPart;
|
||||||
|
|
||||||
|
Status = FsdReadFile(DeviceExt,FileObject,Buffer,Length,Offset);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = Length;
|
||||||
|
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PDEVICE_EXTENSION DeviceExt;
|
||||||
|
|
||||||
|
IoCreateDevice(DriverObject,
|
||||||
|
sizeof(DEVICE_EXTENSION),
|
||||||
|
NULL,
|
||||||
|
FILE_DEVICE_FILE_SYSTEM,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
&DeviceObject);
|
||||||
|
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
|
||||||
|
DeviceExt = (PVOID)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
FsdMountDevice(DeviceExt,DeviceToMount);
|
||||||
|
|
||||||
|
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
|
||||||
|
DeviceToMount);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PVPB vpb = Stack->Parameters.Mount.Vpb;
|
||||||
|
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("<VFAT> FSC\n");
|
||||||
|
|
||||||
|
if (FsdHasFileSystem(DeviceToMount))
|
||||||
|
{
|
||||||
|
Status = FsdMount(DeviceToMount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("<VFAT> Unrecognized Volume\n");
|
||||||
|
Status = STATUS_UNRECOGNIZED_VOLUME;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
|
PUNICODE_STRING RegistryPath)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Called by the system to initalize the driver
|
||||||
|
* ARGUMENTS:
|
||||||
|
* DriverObject = object describing this driver
|
||||||
|
* RegistryPath = path to our configuration entries
|
||||||
|
* RETURNS: Success or failure
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
NTSTATUS ret;
|
||||||
|
UNICODE_STRING ustr;
|
||||||
|
ANSI_STRING astr;
|
||||||
|
|
||||||
|
DbgPrint("VFAT 0.0.1\n");
|
||||||
|
|
||||||
|
DriverObject = _DriverObject;
|
||||||
|
|
||||||
|
RtlInitAnsiString(&astr,"\\Device\\VFAT");
|
||||||
|
RtlAnsiStringToUnicodeString(&ustr,&astr,TRUE);
|
||||||
|
ret = IoCreateDevice(DriverObject,0,&ustr,
|
||||||
|
FILE_DEVICE_FILE_SYSTEM,0,FALSE,&DeviceObject);
|
||||||
|
if (ret!=STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceObject->Flags=0;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_READ] = FsdRead;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
||||||
|
FsdFileSystemControl;
|
||||||
|
DriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
|
IoRegisterFileSystem(DeviceObject);
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
9
reactos/drivers/fs/vfat/makefile
Normal file
9
reactos/drivers/fs/vfat/makefile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
%.o: %.cc
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
%.o: %.asm
|
||||||
|
$(NASM) $(NFLAGS) $< -o $@
|
||||||
|
|
||||||
|
all: blockdev.o iface.o
|
||||||
|
$(LD) iface.o blockdev.o -r -o vfatfsd.o
|
||||||
|
|
||||||
|
include ../../../rules.mak
|
47
reactos/drivers/fs/vfat/vfat.h
Normal file
47
reactos/drivers/fs/vfat/vfat.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
BOOLEAN VFATReadSector(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
|
IN ULONG DiskSector,
|
||||||
|
IN UCHAR* Buffer);
|
||||||
|
|
||||||
|
struct _BootSector {
|
||||||
|
unsigned char magic0, res0, magic1;
|
||||||
|
unsigned char OEMName[8];
|
||||||
|
unsigned short BytesPerSector;
|
||||||
|
unsigned char SectorsPerCluster;
|
||||||
|
unsigned short ReservedSectors;
|
||||||
|
unsigned char FATCount;
|
||||||
|
unsigned short RootEntries, Sectors;
|
||||||
|
unsigned char Media;
|
||||||
|
unsigned short FATSectors, SectorsPerTrack, Heads;
|
||||||
|
unsigned long HiddenSectors, SectorsHuge;
|
||||||
|
unsigned char Drive, Res1, Sig;
|
||||||
|
unsigned long VolumeID;
|
||||||
|
unsigned char VolumeLabel[11], SysType[8];
|
||||||
|
unsigned char Res2[450];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
typedef struct _BootSector BootSector;
|
||||||
|
|
||||||
|
struct _FATDirEntry {
|
||||||
|
unsigned char Filename[8], Ext[3], Attrib, Res[14];
|
||||||
|
unsigned short FirstCluster;
|
||||||
|
unsigned long FileSize;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
typedef struct _FATDirEntry FATDirEntry;
|
||||||
|
|
||||||
|
struct _slot
|
||||||
|
{
|
||||||
|
unsigned char id; // sequence number for slot
|
||||||
|
WCHAR name0_4[5]; // first 5 characters in name
|
||||||
|
unsigned char attr; // attribute byte
|
||||||
|
unsigned char reserved; // always 0
|
||||||
|
unsigned char alias_checksum; // checksum for 8.3 alias
|
||||||
|
WCHAR name5_10[6]; // 6 more characters in name
|
||||||
|
unsigned char start[2]; // starting cluster number
|
||||||
|
WCHAR name11_12[2]; // last 2 characters in name
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _slot slot;
|
||||||
|
|
||||||
|
#define BLOCKSIZE 512
|
BIN
reactos/iface/native/genntdll
Normal file
BIN
reactos/iface/native/genntdll
Normal file
Binary file not shown.
129
reactos/iface/native/genntdll.c
Normal file
129
reactos/iface/native/genntdll.c
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS version of ntdll
|
||||||
|
* FILE: lib/ntdll/genntdll.c
|
||||||
|
* PURPOSE: Generates the system call stubs in ntdll
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDE ******************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
int process(FILE* in, FILE* out, FILE *out2)
|
||||||
|
{
|
||||||
|
char line[255];
|
||||||
|
char* s;
|
||||||
|
char* name;
|
||||||
|
char* name2;
|
||||||
|
int value;
|
||||||
|
char* nr_args;
|
||||||
|
|
||||||
|
unsigned char first1 = TRUE;
|
||||||
|
|
||||||
|
fprintf(out,"; Machine generated, don't edit\n");
|
||||||
|
fprintf(out,"\n\n");
|
||||||
|
fprintf(out,"SECTION .text\n\n");
|
||||||
|
|
||||||
|
fprintf(out2,"// Machine generated, don't edit\n");
|
||||||
|
fprintf(out2,"\n\n");
|
||||||
|
//fprintf(out2,"#include <ntddk.h>");
|
||||||
|
fprintf(out2,"\n\n\n");
|
||||||
|
fprintf(out2,"SERVICE_TABLE _SystemServiceTable[256] = {\n");
|
||||||
|
|
||||||
|
|
||||||
|
value = 0;
|
||||||
|
while (!feof(in) && fgets(line,255,in) != NULL)
|
||||||
|
{
|
||||||
|
// fgets(line,255,in);
|
||||||
|
if ((s=(char *)strchr(line,'\n'))!=NULL)
|
||||||
|
{
|
||||||
|
*s=0;
|
||||||
|
}
|
||||||
|
s=&line[0];
|
||||||
|
if ((*s)!='#')
|
||||||
|
{
|
||||||
|
name = (char *)strtok(s," \t");
|
||||||
|
name2 = (char *)strtok(NULL," \t");
|
||||||
|
// value = strtok(NULL," \t");
|
||||||
|
nr_args = (char *)strtok(NULL," \t");
|
||||||
|
|
||||||
|
// printf("name %s value %d\n",name,value);
|
||||||
|
fprintf(out,"GLOBAL _%s\n",name);
|
||||||
|
fprintf(out,"GLOBAL _%s\n",name2);
|
||||||
|
fprintf(out,"_%s:\n",name);
|
||||||
|
fprintf(out,"_%s:\n",name2);
|
||||||
|
fprintf(out,"\tmov\teax,%d\n",value);
|
||||||
|
fprintf(out,"\tlea\tedx,[esp+4]\n");
|
||||||
|
fprintf(out,"\tint\t2Eh\n");
|
||||||
|
fprintf(out,"\tret\t%s\n\n",nr_args);
|
||||||
|
|
||||||
|
|
||||||
|
value++;
|
||||||
|
|
||||||
|
if ( first1 == TRUE )
|
||||||
|
first1 = FALSE;
|
||||||
|
else
|
||||||
|
fprintf(out2,",\n");
|
||||||
|
|
||||||
|
fprintf(out2,"\t\t{ %s, (ULONG)%s }",nr_args,name);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out2,"\n};\n");
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void usage(void)
|
||||||
|
{
|
||||||
|
printf("Usage: genntdll sysfuncs.lst outfile.asm outfile.h\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
FILE* in;
|
||||||
|
FILE* out;
|
||||||
|
FILE *out2;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (argc!=4)
|
||||||
|
{
|
||||||
|
usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
in = fopen(argv[1],"rb");
|
||||||
|
if (in==NULL)
|
||||||
|
{
|
||||||
|
perror("Failed to open input file");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
out = fopen(argv[2],"wb");
|
||||||
|
if (out==NULL)
|
||||||
|
{
|
||||||
|
perror("Failed to open output file");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
out2 = fopen(argv[3],"wb");
|
||||||
|
if (out2==NULL)
|
||||||
|
{
|
||||||
|
perror("Failed to open output file");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = process(in,out,out2);
|
||||||
|
|
||||||
|
fclose(in);
|
||||||
|
fclose(out);
|
||||||
|
fclose(out2);
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
19
reactos/iface/native/makefile
Normal file
19
reactos/iface/native/makefile
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
all: genntdll$(EXE_POSTFIX) ../../lib/ntdll/napi.asm
|
||||||
|
|
||||||
|
../../lib/ntdll/napi.asm: sysfuncs.lst genntdll$(EXE_POSTFIX) ../../include/ntdll/napi.h
|
||||||
|
genntdll$(EXE_POSTFIX) sysfuncs.lst ../../lib/ntdll/napi.asm ../../include/ntdll/napi.h
|
||||||
|
|
||||||
|
../../include/ntdll/napi.h: dummy
|
||||||
|
|
||||||
|
genntdll$(EXE_POSTFIX): genntdll.c
|
||||||
|
$(NATIVE_CC) -g genntdll.c -o genntdll$(EXE_POSTFIX)
|
||||||
|
|
||||||
|
sysfuncs.lst: dummy
|
||||||
|
|
||||||
|
clean: dummy
|
||||||
|
$(RM) ../../lib/ntdll/sysfuncs.lst
|
||||||
|
$(RM) ../../include/ntdll/napi.h
|
||||||
|
|
||||||
|
dummy:
|
||||||
|
|
||||||
|
include ../../rules.mak
|
210
reactos/iface/native/sysfuncs.lst
Normal file
210
reactos/iface/native/sysfuncs.lst
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
NtAcceptConnectPort ZwAcceptConnectPort 24
|
||||||
|
NtAccessCheck ZwAccessCheck 32
|
||||||
|
NtAccessCheckAndAuditAlarm ZwAccessCheckAndAuditAlarm 44
|
||||||
|
NtAddAtom ZwAddAtom 8
|
||||||
|
NtAdjustGroupsToken ZwAdjustGroupsToken 24
|
||||||
|
NtAdjustPrivilegesToken ZwAdjustPrivilegesToken 24
|
||||||
|
NtAlertResumeThread ZwAlertResumeThread 8
|
||||||
|
NtAlertThread ZwAlertThread 4
|
||||||
|
NtAllocateLocallyUniqueId ZwAllocateLocallyUniqueId 4
|
||||||
|
NtAllocateUuids ZwAllocateUuids 12
|
||||||
|
NtAllocateVirtualMemory ZwAllocateVirtualMemory 24
|
||||||
|
NtCallbackReturn ZwCallbackReturn 12
|
||||||
|
NtCancelIoFile ZwCancelIoFile 8
|
||||||
|
NtCancelTimer ZwCancelTimer 8
|
||||||
|
NtClearEvent ZwClearEvent 4
|
||||||
|
NtClose ZwClose 4
|
||||||
|
NtCloseObjectAuditAlarm ZwCloseObjectAuditAlarm 12
|
||||||
|
NtCompleteConnectPort ZwCompleteConnectPort 4
|
||||||
|
NtConnectPort ZwConnectPort 32
|
||||||
|
NtContinue ZwContinue 8
|
||||||
|
NtCreateDirectoryObject ZwCreateDirectoryObject 12
|
||||||
|
NtCreateEvent ZwCreateEvent 20
|
||||||
|
NtCreateEventPair ZwCreateEventPair 12
|
||||||
|
NtCreateFile ZwCreateFile 44
|
||||||
|
NtCreateIoCompletion ZwCreateIoCompletion 16
|
||||||
|
NtCreateKey ZwCreateKey 28
|
||||||
|
NtCreateMailslotFile ZwCreateMailslotFile 32
|
||||||
|
NtCreateMutant ZwCreateMutant 16
|
||||||
|
NtCreateNamedPipeFile ZwCreateNamedPipeFile 56
|
||||||
|
NtCreatePagingFile ZwCreatePagingFile 16
|
||||||
|
NtCreatePort ZwCreatePort 20
|
||||||
|
NtCreateProcess ZwCreateProcess 32
|
||||||
|
NtCreateProfile ZwCreateProfile 36
|
||||||
|
NtCreateSection ZwCreateSection 28
|
||||||
|
NtCreateSemaphore ZwCreateSemaphore 20
|
||||||
|
NtCreateSymbolicLinkObject ZwCreateSymbolicLinkObject 16
|
||||||
|
NtCreateThread ZwCreateThread 32
|
||||||
|
NtCreateTimer ZwCreateTimer 16
|
||||||
|
NtCreateToken ZwCreateToken 52
|
||||||
|
NtDelayExecution ZwDelayExecution 8
|
||||||
|
NtDeleteAtom ZwDeleteAtom 4
|
||||||
|
NtDeleteFile ZwDeleteFile 4
|
||||||
|
NtDeleteKey ZwDeleteKey 4
|
||||||
|
NtDeleteObjectAuditAlarm ZwDeleteObjectAuditAlarm 12
|
||||||
|
NtDeleteValueKey ZwDeleteValueKey 8
|
||||||
|
NtDeviceIoControlFile ZwDeviceIoControlFile 40
|
||||||
|
NtDisplayString ZwDisplayString 4
|
||||||
|
NtDuplicateObject ZwDuplicateObject 28
|
||||||
|
NtDuplicateToken ZwDuplicateToken 24
|
||||||
|
NtEnumerateKey ZwEnumerateKey 24
|
||||||
|
NtEnumerateValueKey ZwEnumerateValueKey 24
|
||||||
|
NtExtendSection ZwExtendSection 8
|
||||||
|
NtFindAtom ZwFindAtom 8
|
||||||
|
NtFlushBuffersFile ZwFlushBuffersFile 8
|
||||||
|
NtFlushInstructionCache ZwFlushInstructionCache 12
|
||||||
|
NtFlushKey ZwFlushKey 4
|
||||||
|
NtFlushVirtualMemory ZwFlushVirtualMemory 16
|
||||||
|
NtFlushWriteBuffer ZwFlushWriteBuffer 0
|
||||||
|
NtFreeVirtualMemory ZwFreeVirtualMemory 16
|
||||||
|
NtFsControlFile ZwFsControlFile 40
|
||||||
|
NtGetContextThread ZwGetContextThread 8
|
||||||
|
NtGetPlugPlayEvent ZwGetPlugPlayEvent 16
|
||||||
|
NtGetTickCount ZwGetTickCount 0
|
||||||
|
NtImpersonateClientOfPort ZwImpersonateClientOfPort 8
|
||||||
|
NtImpersonateThread ZwImpersonateThread 12
|
||||||
|
NtInitializeRegistry ZwInitializeRegistry 4
|
||||||
|
NtListenPort ZwListenPort 8
|
||||||
|
NtLoadDriver ZwLoadDriver 4
|
||||||
|
NtLoadKey ZwLoadKey 8
|
||||||
|
NtLoadKey2 ZwLoadKey2 12
|
||||||
|
NtLockFile ZwLockFile 40
|
||||||
|
NtLockVirtualMemory ZwLockVirtualMemory 16
|
||||||
|
NtMakeTemporaryObject ZwMakeTemporaryObject 4
|
||||||
|
NtMapViewOfSection ZwMapViewOfSection 40
|
||||||
|
NtNotifyChangeDirectoryFile ZwNotifyChangeDirectoryFile 36
|
||||||
|
NtNotifyChangeKey ZwNotifyChangeKey 40
|
||||||
|
NtOpenDirectoryObject ZwOpenDirectoryObject 12
|
||||||
|
NtOpenEvent ZwOpenEvent 12
|
||||||
|
NtOpenEventPair ZwOpenEventPair 12
|
||||||
|
NtOpenFile ZwOpenFile 24
|
||||||
|
NtOpenIoCompletion ZwOpenIoCompletion 12
|
||||||
|
NtOpenKey ZwOpenKey 12
|
||||||
|
NtOpenMutant ZwOpenMutant 12
|
||||||
|
NtOpenObjectAuditAlarm ZwOpenObjectAuditAlarm 48
|
||||||
|
NtOpenProcess ZwOpenProcess 16
|
||||||
|
NtOpenProcessToken ZwOpenProcessToken 12
|
||||||
|
NtOpenSection ZwOpenSection 12
|
||||||
|
NtOpenSemaphore ZwOpenSemaphore 12
|
||||||
|
NtOpenSymbolicLinkObject ZwOpenSymbolicLinkObject 12
|
||||||
|
NtOpenThread ZwOpenThread 16
|
||||||
|
NtOpenThreadToken ZwOpenThreadToken 16
|
||||||
|
NtOpenTimer ZwOpenTimer 12
|
||||||
|
NtPlugPlayControl ZwPlugPlayControl 16
|
||||||
|
NtPrivilegeCheck ZwPrivilegeCheck 12
|
||||||
|
NtPrivilegedServiceAuditAlarm ZwPrivilegedServiceAuditAlarm 20
|
||||||
|
NtPrivilegeObjectAuditAlarm ZwPrivilegeObjectAuditAlarm 24
|
||||||
|
NtProtectVirtualMemory ZwProtectVirtualMemory 20
|
||||||
|
NtPulseEvent ZwPulseEvent 8
|
||||||
|
NtQueryInformationAtom ZwQueryInformationAtom 20
|
||||||
|
NtQueryAttributesFile ZwQueryAttributesFile 8
|
||||||
|
NtQueryDefaultLocale ZwQueryDefaultLocale 8
|
||||||
|
NtQueryDirectoryFile ZwQueryDirectoryFile 44
|
||||||
|
NtQueryDirectoryObject ZwQueryDirectoryObject 28
|
||||||
|
NtQueryEaFile ZwQueryEaFile 36
|
||||||
|
NtQueryEvent ZwQueryEvent 20
|
||||||
|
NtQueryFullAttributesFile ZwQueryFullAttributesFile 8
|
||||||
|
NtQueryInformationFile ZwQueryInformationFile 20
|
||||||
|
NtQueryIoCompletion ZwQueryIoCompletion 20
|
||||||
|
NtQueryInformationPort ZwQueryInformationPort 20
|
||||||
|
NtQueryInformationProcess ZwQueryInformationProcess 20
|
||||||
|
NtQueryInformationThread ZwQueryInformationThread 20
|
||||||
|
NtQueryInformationToken ZwQueryInformationToken 20
|
||||||
|
NtQueryIntervalProfile ZwQueryIntervalProfile 8
|
||||||
|
NtQueryKey ZwQueryKey 20
|
||||||
|
NtQueryMultipleValueKey ZwQueryMultipleValueKey 24
|
||||||
|
NtQueryMutant ZwQueryMutant 20
|
||||||
|
NtQueryObject ZwQueryObject 20
|
||||||
|
NtQueryOleDirectoryFile ZwQueryOleDirectoryFile 44
|
||||||
|
NtQueryPerformanceCounter ZwQueryPerformanceCounter 8
|
||||||
|
NtQuerySection ZwQuerySection 20
|
||||||
|
NtQuerySecurityObject ZwQuerySecurityObject 20
|
||||||
|
NtQuerySemaphore ZwQuerySemaphore 20
|
||||||
|
NtQuerySymbolicLinkObject ZwQuerySymbolicLinkObject 12
|
||||||
|
NtQuerySystemEnvironmentValue ZwQuerySystemEnvironmentValue 16
|
||||||
|
NtQuerySystemInformation ZwQuerySystemInformation 16
|
||||||
|
NtQuerySystemTime ZwQuerySystemTime 4
|
||||||
|
NtQueryTimer ZwQueryTimer 20
|
||||||
|
NtQueryTimerResolution ZwQueryTimerResolution 12
|
||||||
|
NtQueryValueKey ZwQueryValueKey 24
|
||||||
|
NtQueryVirtualMemory ZwQueryVirtualMemory 24
|
||||||
|
NtQueryVolumeInformationFile ZwQueryVolumeInformationFile 20
|
||||||
|
NtQueueApcThread ZwQueueApcThread 20
|
||||||
|
NtRaiseException ZwRaiseException 12
|
||||||
|
NtRaiseHardError ZwRaiseHardError 24
|
||||||
|
NtReadFile ZwReadFile 36
|
||||||
|
NtReadFileScatter ZwReadFileScatter 36
|
||||||
|
NtReadRequestData ZwReadRequestData 24
|
||||||
|
NtReadVirtualMemory ZwReadVirtualMemory 20
|
||||||
|
NtRegisterThreadTerminatePort ZwRegisterThreadTerminatePort 4
|
||||||
|
NtReleaseMutant ZwReleaseMutant 8
|
||||||
|
NtReleaseSemaphore ZwReleaseSemaphore 12
|
||||||
|
NtRemoveIoCompletion ZwRemoveIoCompletion 20
|
||||||
|
NtReplaceKey ZwReplaceKey 12
|
||||||
|
NtReplyPort ZwReplyPort 8
|
||||||
|
NtReplyWaitReceivePort ZwReplyWaitReceivePort 16
|
||||||
|
NtReplyWaitReplyPort ZwReplyWaitReplyPort 8
|
||||||
|
NtRequestPort ZwRequestPort 8
|
||||||
|
NtRequestWaitReplyPort ZwRequestWaitReplyPort 12
|
||||||
|
NtResetEvent ZwResetEvent 8
|
||||||
|
NtRestoreKey ZwRestoreKey 12
|
||||||
|
NtResumeThread ZwResumeThread 8
|
||||||
|
NtSaveKey ZwSaveKey 8
|
||||||
|
NtSetIoCompletion ZwSetIoCompletion 20
|
||||||
|
NtSetContextThread ZwSetContextThread 8
|
||||||
|
NtSetDefaultHardErrorPort ZwSetDefaultHardErrorPort 4
|
||||||
|
NtSetDefaultLocale ZwSetDefaultLocale 8
|
||||||
|
NtSetEaFile ZwSetEaFile 16
|
||||||
|
NtSetEvent ZwSetEvent 8
|
||||||
|
NtSetHighEventPair ZwSetHighEventPair 4
|
||||||
|
NtSetHighWaitLowEventPair ZwSetHighWaitLowEventPair 4
|
||||||
|
NtSetInformationFile ZwSetInformationFile 20
|
||||||
|
NtSetInformationKey ZwSetInformationKey 16
|
||||||
|
NtSetInformationObject ZwSetInformationObject 16
|
||||||
|
NtSetInformationProcess ZwSetInformationProcess 16
|
||||||
|
NtSetInformationThread ZwSetInformationThread 16
|
||||||
|
NtSetInformationToken ZwSetInformationToken 16
|
||||||
|
NtSetIntervalProfile ZwSetIntervalProfile 8
|
||||||
|
NtSetLdtEntries ZwSetLdtEntries 24
|
||||||
|
NtSetLowEventPair ZwSetLowEventPair 4
|
||||||
|
NtSetLowWaitHighEventPair ZwSetLowWaitHighEventPair 4
|
||||||
|
NtSetSecurityObject ZwSetSecurityObject 12
|
||||||
|
NtSetSystemEnvironmentValue ZwSetSystemEnvironmentValue 8
|
||||||
|
NtSetSystemInformation ZwSetSystemInformation 12
|
||||||
|
NtSetSystemPowerState ZwSetSystemPowerState 12
|
||||||
|
NtSetSystemTime ZwSetSystemTime 8
|
||||||
|
NtSetTimer ZwSetTimer 28
|
||||||
|
NtSetTimerResolution ZwSetTimerResolution 12
|
||||||
|
NtSetValueKey ZwSetValueKey 24
|
||||||
|
NtSetVolumeInformationFile ZwSetVolumeInformationFile 20
|
||||||
|
NtShutdownSystem ZwShutdownSystem 4
|
||||||
|
NtSignalAndWaitForSingleObject ZwSignalAndWaitForSingleObject 16
|
||||||
|
NtStartProfile ZwStartProfile 4
|
||||||
|
NtStopProfile ZwStopProfile 4
|
||||||
|
NtSuspendThread ZwSuspendThread 8
|
||||||
|
NtSystemDebugControl ZwSystemDebugControl 24
|
||||||
|
NtTerminateProcess ZwTerminateProcess 8
|
||||||
|
NtTerminateThread ZwTerminateThread 8
|
||||||
|
NtTestAlert ZwTestAlert 0
|
||||||
|
NtUnloadDriver ZwUnloadDriver 4
|
||||||
|
NtUnloadKey ZwUnloadKey 4
|
||||||
|
NtUnlockFile ZwUnlockFile 20
|
||||||
|
NtUnlockVirtualMemory ZwUnlockVirtualMemory 16
|
||||||
|
NtUnmapViewOfSection ZwUnmapViewOfSection 8
|
||||||
|
NtVdmControl ZwVdmControl 8
|
||||||
|
NtWaitForMultipleObjects ZwWaitForMultipleObjects 20
|
||||||
|
NtWaitForSingleObject ZwWaitForSingleObject 12
|
||||||
|
NtWaitHighEventPair ZwWaitHighEventPair 4
|
||||||
|
NtWaitLowEventPair ZwWaitLowEventPair 4
|
||||||
|
NtWriteFile ZwWriteFile 36
|
||||||
|
NtWriteFileGather ZwWriteFileGather 36
|
||||||
|
NtWriteRequestData ZwWriteRequestData 24
|
||||||
|
NtWriteVirtualMemory ZwWriteVirtualMemory 20
|
||||||
|
NtW32Call ZwW32Call 20
|
||||||
|
NtCreateChannel ZwCreateChannel 8
|
||||||
|
NtListenChannel ZwListenChannel 8
|
||||||
|
NtOpenChannel ZwOpenChannel 8
|
||||||
|
NtReplyWaitSendChannel ZwReplyWaitSendChannel 12
|
||||||
|
NtSendWaitReplyChannel ZwSendWaitReplyChannel 16
|
||||||
|
NtSetContextChannel ZwSetContextChannel 4
|
||||||
|
NtYieldExecution ZwYieldExecution 0
|
4
reactos/include/ddk/ccfuncs.h
Normal file
4
reactos/include/ddk/ccfuncs.h
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
VOID CbInitDccb(PDCCB Dccb, PDEVICE_OBJECT DeviceObject, ULONG SectorSize,
|
||||||
|
ULONG NrSectors, ULONG PercentageToCache);
|
||||||
|
PCCB CbAcquireForRead(PDCCB Dccb, ULONG BlockNr);
|
||||||
|
VOID CbReleaseFromRead(PDCCB Dccb, PCCB Ccb);
|
43
reactos/include/ddk/cctypes.h
Normal file
43
reactos/include/ddk/cctypes.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef __INCLUDE_DDK_CCTYPES_H
|
||||||
|
#define __INCLUDE_DDK_CCTYPES_H
|
||||||
|
|
||||||
|
typedef struct _CCB
|
||||||
|
{
|
||||||
|
ULONG BlockNr;
|
||||||
|
PVOID Buffer;
|
||||||
|
ULONG State;
|
||||||
|
ULONG ActiveReaders;
|
||||||
|
BOOLEAN WriteInProgress;
|
||||||
|
BOOLEAN ActiveWriter;
|
||||||
|
ULONG References;
|
||||||
|
KEVENT FinishedNotify;
|
||||||
|
KSPIN_LOCK Lock;
|
||||||
|
BOOLEAN Modified;
|
||||||
|
LIST_ENTRY Entry;
|
||||||
|
} CCB, *PCCB;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CCB_INVALID,
|
||||||
|
CCB_NOT_CACHED,
|
||||||
|
CCB_CACHED,
|
||||||
|
CCB_DELETE_PENDING,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _DCCB
|
||||||
|
/*
|
||||||
|
* PURPOSE: Device cache control block
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PCCB* HashTbl;
|
||||||
|
ULONG HashTblSize;
|
||||||
|
KSPIN_LOCK HashTblLock;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
ULONG SectorSize;
|
||||||
|
LIST_ENTRY CcbListHead;
|
||||||
|
KSPIN_LOCK CcbListLock;
|
||||||
|
ULONG NrCcbs;
|
||||||
|
ULONG NrModifiedCcbs;
|
||||||
|
} DCCB, *PDCCB;
|
||||||
|
|
||||||
|
#endif /* __INCLUDE_DDK_CCTYPES_H */
|
18
reactos/include/ddk/ntifs.h
Normal file
18
reactos/include/ddk/ntifs.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef __INCLUDE_DDK_NTIFS_H
|
||||||
|
#define __INCLUDE_DDK_NTIFS_H
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BOOLEAN Replace;
|
||||||
|
HANDLE RootDir;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[1];
|
||||||
|
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ddk/cctypes.h>
|
||||||
|
|
||||||
|
#include <ddk/ccfuncs.h>
|
||||||
|
|
||||||
|
#endif /* __INCLUDE_DDK_NTIFS_H */
|
25
reactos/include/ddk/sefuncs.h
Normal file
25
reactos/include/ddk/sefuncs.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
BOOLEAN SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
|
IN PSECURITY_DESCRIPTOR_CONTEXT SubjectSecurityContext,
|
||||||
|
IN BOOLEAN SubjectContextLocked,
|
||||||
|
IN ACCESS_MASK DesiredAccess,
|
||||||
|
IN ACCESS_MASK PreviouslyGrantedAccess,
|
||||||
|
OUT PPRIVILEGE_SET* Privileges,
|
||||||
|
IN PGENERIC_MAPPING GenericMapping,
|
||||||
|
IN KPROCESSOR_MODE AccessMode,
|
||||||
|
OUT PACCESS_MODE GrantedAccess,
|
||||||
|
OUT PNTSTATUS AccessStatus);
|
||||||
|
|
||||||
|
NTSTATUS SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
|
||||||
|
PSECURITY_DESCRIPTOR ExplicitDescriptor,
|
||||||
|
BOOLEAN IsDirectoryObject,
|
||||||
|
PSECURITY_SUBJECT_CONTEXT SubjectContext,
|
||||||
|
PGENERIC_MAPPING GenericMapping,
|
||||||
|
POOL_TYPE PoolType);
|
||||||
|
|
||||||
|
NTSTATUS SeDeassignSecurity(PSECURITY_DESCRIPTOR* SecurityDescriptor);
|
||||||
|
|
||||||
|
BOOLEAN SeSinglePrivilegeCheck(LUID PrivilegeValue,
|
||||||
|
KPROCESSOR_MODE PreviousMode);
|
||||||
|
|
||||||
|
|
||||||
|
|
695
reactos/include/ddk/zwtypes.h
Normal file
695
reactos/include/ddk/zwtypes.h
Normal file
|
@ -0,0 +1,695 @@
|
||||||
|
#ifndef __INCLUDE_DDK_ZWTYPES_H
|
||||||
|
#define __INCLUDE_DDK_ZWTYPES_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define NtCurrentProcess() ( (HANDLE) 0xFFFFFFFF )
|
||||||
|
#define NtCurrentThread() ( (HANDLE) 0xFFFFFFFE )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// event access mask
|
||||||
|
|
||||||
|
#define EVENT_READ_ACCESS 1
|
||||||
|
#define EVENT_WRITE_ACCESS 2
|
||||||
|
|
||||||
|
|
||||||
|
// file disposition values
|
||||||
|
|
||||||
|
|
||||||
|
#define FILE_SUPERSEDE 0x0000
|
||||||
|
#define FILE_OPEN 0x0001
|
||||||
|
#define FILE_CREATE 0x0002
|
||||||
|
#define FILE_OPEN_IF 0x0003
|
||||||
|
#define FILE_OVERWRITE 0x0004
|
||||||
|
#define FILE_OVERWRITE_IF 0x0005
|
||||||
|
#define FILE_MAXIMUM_DISPOSITION 0x0005
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//process query / set information class
|
||||||
|
|
||||||
|
#define ProcessBasicInformation 0
|
||||||
|
#define ProcessQuotaLimits 1
|
||||||
|
#define ProcessIoCounters 2
|
||||||
|
#define ProcessVmCounters 3
|
||||||
|
#define ProcessTimes 4
|
||||||
|
#define ProcessBasePriority 5
|
||||||
|
#define ProcessRaisePriority 6
|
||||||
|
#define ProcessDebugPort 7
|
||||||
|
#define ProcessExceptionPort 8
|
||||||
|
#define ProcessAccessToken 9
|
||||||
|
#define ProcessLdtInformation 10
|
||||||
|
#define ProcessLdtSize 11
|
||||||
|
#define ProcessDefaultHardErrorMode 12
|
||||||
|
#define ProcessIoPortHandlers 13
|
||||||
|
#define ProcessPooledUsageAndLimits 14
|
||||||
|
#define ProcessWorkingSetWatch 15
|
||||||
|
#define ProcessUserModeIOPL 16
|
||||||
|
#define ProcessEnableAlignmentFaultFixup 17
|
||||||
|
#define ProcessPriorityClass 18
|
||||||
|
#define ProcessWx86Information 19
|
||||||
|
#define ProcessHandleCount 20
|
||||||
|
#define ProcessAffinityMask 21
|
||||||
|
#define MaxProcessInfoClass 22
|
||||||
|
|
||||||
|
// thread query / set information class
|
||||||
|
#define ThreadBasicInformation 0
|
||||||
|
#define ThreadTimes 1
|
||||||
|
#define ThreadPriority 2
|
||||||
|
#define ThreadBasePriority 3
|
||||||
|
#define ThreadAffinityMask 4
|
||||||
|
#define ThreadImpersonationToken 5
|
||||||
|
#define ThreadDescriptorTableEntry 6
|
||||||
|
#define ThreadEnableAlignmentFaultFixup 7
|
||||||
|
#define ThreadEventPair 8
|
||||||
|
#define ThreadQuerySetWin32StartAddress 9
|
||||||
|
#define ThreadZeroTlsCell 10
|
||||||
|
#define ThreadPerformanceCount 11
|
||||||
|
#define ThreadAmILastThread 12
|
||||||
|
#define ThreadIdealProcessor 13
|
||||||
|
#define ThreadPriorityBoost 14
|
||||||
|
#define MaxThreadInfoClass 15
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// key query information class
|
||||||
|
|
||||||
|
#define KeyBasicInformation 0
|
||||||
|
#define KeyNodeInformation 1
|
||||||
|
#define KeyFullInformation 2
|
||||||
|
|
||||||
|
|
||||||
|
// key set information class
|
||||||
|
|
||||||
|
#define KeyWriteTimeInformation 0
|
||||||
|
|
||||||
|
// key value information class
|
||||||
|
|
||||||
|
#define KeyValueBasicInformation 0
|
||||||
|
#define KeyValueFullInformation 1
|
||||||
|
#define KeyValuePartialInformation 2
|
||||||
|
|
||||||
|
// object handle information
|
||||||
|
|
||||||
|
#define ObjectBasicInformation 0
|
||||||
|
#define ObjectNameInformation 1
|
||||||
|
#define ObjectTypeInformation 2
|
||||||
|
#define ObjectAllInformation 3
|
||||||
|
#define ObjectDataInformation 4
|
||||||
|
|
||||||
|
// semaphore information
|
||||||
|
|
||||||
|
#define SemaphoreBasicInformation 0
|
||||||
|
|
||||||
|
// event information
|
||||||
|
|
||||||
|
#define EventBasicInformation 0
|
||||||
|
|
||||||
|
|
||||||
|
// system information
|
||||||
|
|
||||||
|
#define SystemPerformanceInformation 5
|
||||||
|
#define SystemCacheInformation 21
|
||||||
|
#define SystemTimeAdjustmentInformation 28
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// shutdown action
|
||||||
|
|
||||||
|
typedef enum SHUTDOWN_ACTION_TAG {
|
||||||
|
ShutdownNoReboot,
|
||||||
|
ShutdownReboot,
|
||||||
|
ShutdownPowerOff
|
||||||
|
} SHUTDOWN_ACTION;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// wait type
|
||||||
|
|
||||||
|
#define WaitAll 0
|
||||||
|
#define WaitAny 1
|
||||||
|
|
||||||
|
|
||||||
|
// key restore flags
|
||||||
|
|
||||||
|
#define REG_WHOLE_HIVE_VOLATILE 1
|
||||||
|
#define REG_REFRESH_HIVE 2
|
||||||
|
|
||||||
|
|
||||||
|
// object type access rights
|
||||||
|
|
||||||
|
#define OBJECT_TYPE_CREATE 0x0001
|
||||||
|
#define OBJECT_TYPE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
|
||||||
|
|
||||||
|
|
||||||
|
// directory access rights
|
||||||
|
|
||||||
|
#define DIRECTORY_QUERY 0x0001
|
||||||
|
#define DIRECTORY_TRAVERSE 0x0002
|
||||||
|
#define DIRECTORY_CREATE_OBJECT 0x0004
|
||||||
|
#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008
|
||||||
|
|
||||||
|
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
|
||||||
|
|
||||||
|
// symbolic link access rights
|
||||||
|
|
||||||
|
#define SYMBOLIC_LINK_QUERY 0x0001
|
||||||
|
#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
|
||||||
|
|
||||||
|
typedef struct _PROCESS_WS_WATCH_INFORMATION
|
||||||
|
{
|
||||||
|
PVOID FaultingPc;
|
||||||
|
PVOID FaultingVa;
|
||||||
|
} PROCESS_WS_WATCH_INFORMATION, *PPROCESS_WS_WATCH_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _PROCESS_BASIC_INFORMATION
|
||||||
|
{
|
||||||
|
NTSTATUS ExitStatus;
|
||||||
|
PNT_PEB PebBaseAddress;
|
||||||
|
KAFFINITY AffinityMask;
|
||||||
|
KPRIORITY BasePriority;
|
||||||
|
ULONG UniqueProcessId;
|
||||||
|
ULONG InheritedFromUniqueProcessId;
|
||||||
|
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _QUOTA_LIMITS
|
||||||
|
{
|
||||||
|
ULONG PagedPoolLimit;
|
||||||
|
ULONG NonPagedPoolLimit;
|
||||||
|
ULONG MinimumWorkingSetSize;
|
||||||
|
ULONG MaximumWorkingSetSize;
|
||||||
|
ULONG PagefileLimit;
|
||||||
|
TIME TimeLimit;
|
||||||
|
} QUOTA_LIMITS, *PQUOTA_LIMITS;
|
||||||
|
|
||||||
|
typedef struct _IO_COUNTERS
|
||||||
|
{
|
||||||
|
ULONG ReadOperationCount;
|
||||||
|
ULONG WriteOperationCount;
|
||||||
|
ULONG OtherOperationCount;
|
||||||
|
LARGE_INTEGER ReadTransferCount;
|
||||||
|
LARGE_INTEGER WriteTransferCount;
|
||||||
|
LARGE_INTEGER OtherTransferCount;
|
||||||
|
} IO_COUNTERS, *PIO_COUNTERS;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _VM_COUNTERS_
|
||||||
|
{
|
||||||
|
ULONG PeakVirtualSize;
|
||||||
|
ULONG VirtualSize;
|
||||||
|
ULONG PageFaultCount;
|
||||||
|
ULONG PeakWorkingSetSize;
|
||||||
|
ULONG WorkingSetSize;
|
||||||
|
ULONG QuotaPeakPagedPoolUsage;
|
||||||
|
ULONG QuotaPagedPoolUsage;
|
||||||
|
ULONG QuotaPeakNonPagedPoolUsage;
|
||||||
|
ULONG QuotaNonPagedPoolUsage;
|
||||||
|
ULONG PagefileUsage;
|
||||||
|
ULONG PeakPagefileUsage;
|
||||||
|
} VM_COUNTERS, *PVM_COUNTERS;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _POOLED_USAGE_AND_LIMITS_
|
||||||
|
{
|
||||||
|
ULONG PeakPagedPoolUsage;
|
||||||
|
ULONG PagedPoolUsage;
|
||||||
|
ULONG PagedPoolLimit;
|
||||||
|
ULONG PeakNonPagedPoolUsage;
|
||||||
|
ULONG NonPagedPoolUsage;
|
||||||
|
ULONG NonPagedPoolLimit;
|
||||||
|
ULONG PeakPagefileUsage;
|
||||||
|
ULONG PagefileUsage;
|
||||||
|
ULONG PagefileLimit;
|
||||||
|
} POOLED_USAGE_AND_LIMITS, *PPOOLED_USAGE_AND_LIMITS;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _PROCESS_ACCESS_TOKEN
|
||||||
|
{
|
||||||
|
HANDLE Token;
|
||||||
|
HANDLE Thread;
|
||||||
|
} PROCESS_ACCESS_TOKEN, *PPROCESS_ACCESS_TOKEN;
|
||||||
|
|
||||||
|
typedef struct _KERNEL_USER_TIMES
|
||||||
|
{
|
||||||
|
TIME CreateTime;
|
||||||
|
TIME ExitTime;
|
||||||
|
TIME KernelTime;
|
||||||
|
TIME UserTime;
|
||||||
|
} KERNEL_USER_TIMES;
|
||||||
|
typedef KERNEL_USER_TIMES *PKERNEL_USER_TIMES;
|
||||||
|
|
||||||
|
// thread information
|
||||||
|
|
||||||
|
// incompatible with MS NT
|
||||||
|
|
||||||
|
typedef struct _THREAD_BASIC_INFORMATION
|
||||||
|
{
|
||||||
|
NTSTATUS ExitStatus;
|
||||||
|
PVOID TebBaseAddress;
|
||||||
|
KAFFINITY AffinityMask;
|
||||||
|
KPRIORITY BasePriority;
|
||||||
|
ULONG UniqueThreadId;
|
||||||
|
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
|
||||||
|
|
||||||
|
// object information
|
||||||
|
|
||||||
|
typedef struct _OBJECT_NAME_INFORMATION
|
||||||
|
{
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _OBJECT_DATA_INFORMATION
|
||||||
|
{
|
||||||
|
BOOL bInheritHanlde;
|
||||||
|
BOOL bProtectFromClose;
|
||||||
|
} OBJECT_DATA_INFORMATION, *POBJECT_DATA_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _OBJECT_TYPE_INFORMATION
|
||||||
|
{
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
UNICODE_STRING Type;
|
||||||
|
ULONG TotalHandles;
|
||||||
|
ULONG ReferenceCount;
|
||||||
|
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
|
||||||
|
|
||||||
|
// system information
|
||||||
|
|
||||||
|
typedef struct _SYSTEM_TIME_ADJUSTMENT
|
||||||
|
{
|
||||||
|
ULONG TimeAdjustment;
|
||||||
|
BOOL TimeAdjustmentDisabled;
|
||||||
|
} SYSTEM_TIME_ADJUSTMENT, *PSYSTEM_TIME_ADJUSTMENT;
|
||||||
|
|
||||||
|
typedef struct _SYSTEM_CONFIGURATION_INFO {
|
||||||
|
union {
|
||||||
|
ULONG OemId;
|
||||||
|
struct {
|
||||||
|
WORD ProcessorArchitecture;
|
||||||
|
WORD Reserved;
|
||||||
|
} tag1;
|
||||||
|
} tag2;
|
||||||
|
ULONG PageSize;
|
||||||
|
PVOID MinimumApplicationAddress;
|
||||||
|
PVOID MaximumApplicationAddress;
|
||||||
|
ULONG ActiveProcessorMask;
|
||||||
|
ULONG NumberOfProcessors;
|
||||||
|
ULONG ProcessorType;
|
||||||
|
ULONG AllocationGranularity;
|
||||||
|
WORD ProcessorLevel;
|
||||||
|
WORD ProcessorRevision;
|
||||||
|
} SYSTEM_CONFIGURATION_INFO, *PSYSTEM_CONFIGURATION_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _SYSTEM_CACHE_INFORMATION {
|
||||||
|
ULONG CurrentSize;
|
||||||
|
ULONG PeakSize;
|
||||||
|
ULONG PageFaultCount;
|
||||||
|
ULONG MinimumWorkingSet;
|
||||||
|
ULONG MaximumWorkingSet;
|
||||||
|
ULONG Unused[4];
|
||||||
|
} SYSTEM_CACHE_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// file information
|
||||||
|
|
||||||
|
typedef struct _FILE_BASIC_INFORMATION
|
||||||
|
{
|
||||||
|
TIME CreationTime;
|
||||||
|
TIME LastAccessTime;
|
||||||
|
TIME LastWriteTime;
|
||||||
|
TIME ChangeTime;
|
||||||
|
ULONG FileAttributes;
|
||||||
|
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_STANDARD_INFORMATION
|
||||||
|
{
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
ULONG NumberOfLinks;
|
||||||
|
BOOLEAN DeletePending;
|
||||||
|
BOOLEAN Directory;
|
||||||
|
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_POSITION_INFORMATION
|
||||||
|
{
|
||||||
|
LARGE_INTEGER CurrentByteOffset;
|
||||||
|
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_ALIGNMENT_INFORMATION
|
||||||
|
{
|
||||||
|
ULONG AlignmentRequirement;
|
||||||
|
} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_DISPOSITION_INFORMATION
|
||||||
|
{
|
||||||
|
BOOLEAN DeleteFile;
|
||||||
|
} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_END_OF_FILE_INFORMATION
|
||||||
|
{
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_NETWORK_OPEN_INFORMATION {
|
||||||
|
TIME CreationTime;
|
||||||
|
TIME LastAccessTime;
|
||||||
|
TIME LastWriteTime;
|
||||||
|
TIME ChangeTime;
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
ULONG FileAttributes;
|
||||||
|
} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_FULL_EA_INFORMATION
|
||||||
|
{
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
UCHAR Flags;
|
||||||
|
UCHAR EaNameLength;
|
||||||
|
USHORT EaValueLength;
|
||||||
|
CHAR EaName[0];
|
||||||
|
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _FILE_EA_INFORMATION {
|
||||||
|
ULONG EaSize;
|
||||||
|
} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _FILE_GET_EA_INFORMATION {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
UCHAR EaNameLength;
|
||||||
|
CHAR EaName[0];
|
||||||
|
} FILE_GET_EA_INFORMATION, *PFILE_GET_EA_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_STREAM_INFORMATION {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG StreamNameLength;
|
||||||
|
LARGE_INTEGER StreamSize;
|
||||||
|
LARGE_INTEGER StreamAllocationSize;
|
||||||
|
WCHAR StreamName[0];
|
||||||
|
} FILE_STREAM_INFORMATION, *PFILE_STREAM_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_ALLOCATION_INFORMATION {
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
} FILE_ALLOCATION_INFORMATION, *PFILE_ALLOCATION_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_NAME_INFORMATION {
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[0];
|
||||||
|
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_NAMES_INFORMATION {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG FileIndex;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[0];
|
||||||
|
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _FILE_RENAME_INFORMATION {
|
||||||
|
BOOLEAN Replace;
|
||||||
|
HANDLE RootDir;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[0];
|
||||||
|
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _FILE_INTERNAL_INFORMATION {
|
||||||
|
LARGE_INTEGER IndexNumber;
|
||||||
|
} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_ACCESS_INFORMATION {
|
||||||
|
ACCESS_MASK AccessFlags;
|
||||||
|
} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _FILE_MODE_INFORMATION {
|
||||||
|
ULONG Mode;
|
||||||
|
} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_COMPRESSION_INFORMATION {
|
||||||
|
LARGE_INTEGER CompressedFileSize;
|
||||||
|
USHORT CompressionFormat;
|
||||||
|
UCHAR CompressionUnitShift;
|
||||||
|
UCHAR ChunkShift;
|
||||||
|
UCHAR ClusterShift;
|
||||||
|
UCHAR Reserved[3];
|
||||||
|
} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_ALL_INFORMATION {
|
||||||
|
FILE_BASIC_INFORMATION BasicInformation;
|
||||||
|
FILE_STANDARD_INFORMATION StandardInformation;
|
||||||
|
FILE_INTERNAL_INFORMATION InternalInformation;
|
||||||
|
FILE_EA_INFORMATION EaInformation;
|
||||||
|
FILE_ACCESS_INFORMATION AccessInformation;
|
||||||
|
FILE_POSITION_INFORMATION PositionInformation;
|
||||||
|
FILE_MODE_INFORMATION ModeInformation;
|
||||||
|
FILE_ALIGNMENT_INFORMATION AlignmentInformation;
|
||||||
|
FILE_NAME_INFORMATION NameInformation;
|
||||||
|
} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;
|
||||||
|
|
||||||
|
// file system information structures
|
||||||
|
|
||||||
|
typedef struct _FILE_FS_DEVICE_INFORMATION {
|
||||||
|
DEVICE_TYPE DeviceType;
|
||||||
|
ULONG Characteristics;
|
||||||
|
} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _FILE_FS_VOLUME_INFORMATION {
|
||||||
|
TIME VolumeCreationTime;
|
||||||
|
ULONG VolumeSerialNumber;
|
||||||
|
ULONG VolumeLabelLength;
|
||||||
|
BOOLEAN SupportsObjects;
|
||||||
|
WCHAR VolumeLabel[0];
|
||||||
|
} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_FS_SIZE_INFORMATION {
|
||||||
|
LARGE_INTEGER TotalAllocationUnits;
|
||||||
|
LARGE_INTEGER AvailableAllocationUnits;
|
||||||
|
ULONG SectorsPerAllocationUnit;
|
||||||
|
ULONG BytesPerSector;
|
||||||
|
} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_FS_ATTRIBUTE_INFORMATION {
|
||||||
|
ULONG FileSystemAttributes;
|
||||||
|
LONG MaximumComponentNameLength;
|
||||||
|
ULONG FileSystemNameLength;
|
||||||
|
WCHAR FileSystemName[0];
|
||||||
|
} FILE_FS_ATTRIBUTE_INFORMATION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
FileSystemAttributes is one of the following values:
|
||||||
|
|
||||||
|
FILE_CASE_SENSITIVE_SEARCH 0x00000001
|
||||||
|
FILE_CASE_PRESERVED_NAMES 0x00000002
|
||||||
|
FILE_UNICODE_ON_DISK 0x00000004
|
||||||
|
FILE_PERSISTENT_ACLS 0x00000008
|
||||||
|
FILE_FILE_COMPRESSION 0x00000010
|
||||||
|
FILE_VOLUME_QUOTAS 0x00000020
|
||||||
|
FILE_VOLUME_IS_COMPRESSED 0x00008000
|
||||||
|
*/
|
||||||
|
typedef struct _FILE_FS_LABEL_INFORMATION {
|
||||||
|
ULONG VolumeLabelLength;
|
||||||
|
WCHAR VolumeLabel[0];
|
||||||
|
} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION;
|
||||||
|
|
||||||
|
// read file scatter / write file scatter
|
||||||
|
//FIXME I am a win32 struct aswell
|
||||||
|
|
||||||
|
typedef union _FILE_SEGMENT_ELEMENT {
|
||||||
|
PVOID Buffer;
|
||||||
|
ULONG Alignment;
|
||||||
|
}FILE_SEGMENT_ELEMENT, *PFILE_SEGMENT_ELEMENT;
|
||||||
|
|
||||||
|
// directory information
|
||||||
|
|
||||||
|
typedef struct _OBJDIR_INFORMATION {
|
||||||
|
UNICODE_STRING ObjectName;
|
||||||
|
UNICODE_STRING ObjectTypeName; // Directory, Device ...
|
||||||
|
UCHAR Data[0];
|
||||||
|
} OBJDIR_INFORMATION, *POBJDIR_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _FILE_DIRECTORY_INFORMATION {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG FileIndex;
|
||||||
|
TIME CreationTime;
|
||||||
|
TIME LastAccessTime;
|
||||||
|
TIME LastWriteTime;
|
||||||
|
TIME ChangeTime;
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
ULONG FileAttributes;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[0];
|
||||||
|
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_FULL_DIRECTORY_INFORMATION {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG FileIndex;
|
||||||
|
TIME CreationTime;
|
||||||
|
TIME LastAccessTime;
|
||||||
|
TIME LastWriteTime;
|
||||||
|
TIME ChangeTime;
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
ULONG FileAttributes;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
ULONG EaSize;
|
||||||
|
WCHAR FileName[0]; // variable size
|
||||||
|
} FILE_FULL_DIRECTORY_INFORMATION, *PFILE_FULL_DIRECTORY_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _FILE_BOTH_DIRECTORY_INFORMATION {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG FileIndex;
|
||||||
|
TIME CreationTime;
|
||||||
|
TIME LastAccessTime;
|
||||||
|
TIME LastWriteTime;
|
||||||
|
TIME ChangeTime;
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
ULONG FileAttributes;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
ULONG EaSize;
|
||||||
|
CHAR ShortNameLength;
|
||||||
|
WCHAR ShortName[12]; // 8.3 name
|
||||||
|
WCHAR FileName[0];
|
||||||
|
} FILE_BOTH_DIRECTORY_INFORMATION, *PFILE_BOTH_DIRECTORY_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
NotifyFilter / CompletionFilter:
|
||||||
|
|
||||||
|
FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001
|
||||||
|
FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002
|
||||||
|
FILE_NOTIFY_CHANGE_NAME 0x00000003
|
||||||
|
FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004
|
||||||
|
FILE_NOTIFY_CHANGE_SIZE 0x00000008
|
||||||
|
FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010
|
||||||
|
FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020
|
||||||
|
FILE_NOTIFY_CHANGE_CREATION 0x00000040
|
||||||
|
FILE_NOTIFY_CHANGE_EA 0x00000080
|
||||||
|
FILE_NOTIFY_CHANGE_SECURITY 0x00000100
|
||||||
|
FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000200
|
||||||
|
FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000400
|
||||||
|
FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _FILE_NOTIFY_INFORMATION {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG Action;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[0];
|
||||||
|
} FILE_NOTIFY_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Action is one of the following values:
|
||||||
|
|
||||||
|
FILE_ACTION_ADDED 0x00000001
|
||||||
|
FILE_ACTION_REMOVED 0x00000002
|
||||||
|
FILE_ACTION_MODIFIED 0x00000003
|
||||||
|
FILE_ACTION_RENAMED_OLD_NAME 0x00000004
|
||||||
|
FILE_ACTION_RENAMED_NEW_NAME 0x00000005
|
||||||
|
FILE_ACTION_ADDED_STREAM 0x00000006
|
||||||
|
FILE_ACTION_REMOVED_STREAM 0x00000007
|
||||||
|
FILE_ACTION_MODIFIED_STREAM 0x00000008
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//FIXME: I am a win32 object
|
||||||
|
typedef
|
||||||
|
VOID
|
||||||
|
(*PTIMERAPCROUTINE)(
|
||||||
|
LPVOID lpArgToCompletionRoutine,
|
||||||
|
DWORD dwTimerLowValue,
|
||||||
|
DWORD dwTimerHighValue
|
||||||
|
);
|
||||||
|
|
||||||
|
// NtProcessStartup parameters
|
||||||
|
|
||||||
|
typedef struct _ENVIRONMENT_INFORMATION {
|
||||||
|
ULONG Unknown[21];
|
||||||
|
UNICODE_STRING CommandLine;
|
||||||
|
UNICODE_STRING ImageFile;
|
||||||
|
} ENVIRONMENT_INFORMATION, *PENVIRONMENT_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _STARTUP_ARGUMENT {
|
||||||
|
ULONG Unknown[3];
|
||||||
|
PENVIRONMENT_INFORMATION Environment;
|
||||||
|
} STARTUP_ARGUMENT, *PSTARTUP_ARGUMENT;
|
||||||
|
|
||||||
|
|
||||||
|
// File System Control commands ( related to defragging )
|
||||||
|
|
||||||
|
#define FSCTL_READ_MFT_RECORD 0x90068 // NTFS only
|
||||||
|
#define FSCTL_GET_VOLUME_BITMAP 0x9006F
|
||||||
|
#define FSCTL_GET_RETRIEVAL_POINTERS 0x90073
|
||||||
|
#define FSCTL_MOVE_FILE 0x90074
|
||||||
|
|
||||||
|
typedef struct _MAPPING_PAIR
|
||||||
|
{
|
||||||
|
ULONGLONG Vcn;
|
||||||
|
ULONGLONG Lcn;
|
||||||
|
} MAPPING_PAIR, *PMAPPING_PAIR;
|
||||||
|
|
||||||
|
typedef struct _GET_RETRIEVAL_DESCRIPTOR
|
||||||
|
{
|
||||||
|
ULONG NumberOfPairs;
|
||||||
|
ULONGLONG StartVcn;
|
||||||
|
MAPPING_PAIR Pair[0]; // variable size
|
||||||
|
} GET_RETRIEVAL_DESCRIPTOR, *PGET_RETRIEVAL_DESCRIPTOR;
|
||||||
|
|
||||||
|
typedef struct _BITMAP_DESCRIPTOR
|
||||||
|
{
|
||||||
|
ULONGLONG StartLcn;
|
||||||
|
ULONGLONG ClustersToEndOfVol;
|
||||||
|
BYTE Map[0]; // variable size
|
||||||
|
} BITMAP_DESCRIPTOR, *PBITMAP_DESCRIPTOR;
|
||||||
|
|
||||||
|
typedef struct _MOVEFILE_DESCRIPTOR
|
||||||
|
{
|
||||||
|
HANDLE FileHandle;
|
||||||
|
ULONG Reserved;
|
||||||
|
LARGE_INTEGER StartVcn;
|
||||||
|
LARGE_INTEGER TargetLcn;
|
||||||
|
ULONG NumVcns;
|
||||||
|
ULONG Reserved1;
|
||||||
|
} MOVEFILE_DESCRIPTOR, *PMOVEFILE_DESCRIPTOR;
|
||||||
|
|
||||||
|
|
||||||
|
// semaphore information
|
||||||
|
|
||||||
|
typedef struct _SEMAPHORE_BASIC_INFORMATION
|
||||||
|
{
|
||||||
|
ULONG CurrentCount;
|
||||||
|
ULONG MaximumCount;
|
||||||
|
} SEMAPHORE_BASIC_INFORMATION, *PSEMAPHORE_BASIC_INFORMATION;
|
||||||
|
|
||||||
|
// event information
|
||||||
|
|
||||||
|
typedef struct _EVENT_BASIC_INFORMATION
|
||||||
|
{
|
||||||
|
BOOL AutomaticReset;
|
||||||
|
BOOL Signaled;
|
||||||
|
} EVENT_BASIC_INFORMATION, *PEVENT_INFORMATION;
|
||||||
|
|
||||||
|
//typedef enum _TIMER_TYPE
|
||||||
|
//{
|
||||||
|
// NotificationTimer,
|
||||||
|
// SynchronizationTimer
|
||||||
|
//} TIMER_TYPE;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
25
reactos/include/internal/asm.inc
Normal file
25
reactos/include/internal/asm.inc
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
%macro DECLARE_EXTERNAL_SYMBOL 1
|
||||||
|
%ifdef coff
|
||||||
|
extern _%1
|
||||||
|
%elifdef win32
|
||||||
|
extern _%1
|
||||||
|
%elifdef elf
|
||||||
|
extern %1
|
||||||
|
_%1:
|
||||||
|
call %1
|
||||||
|
ret
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro DECLARE_GLOBAL_SYMBOL 1
|
||||||
|
%ifdef coff
|
||||||
|
global _%1
|
||||||
|
_%1:
|
||||||
|
%elifdef win32
|
||||||
|
global _%1
|
||||||
|
_%1:
|
||||||
|
%elifdef elf
|
||||||
|
global %1
|
||||||
|
%1:
|
||||||
|
%endif
|
||||||
|
%endmacro
|
93
reactos/include/internal/i386/mmhal.h
Normal file
93
reactos/include/internal/i386/mmhal.h
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Lowlevel memory managment definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __INTERNAL_HAL_PAGE_H
|
||||||
|
#define __INTERNAL_HAL_PAGE_H
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
|
||||||
|
#define PAGESIZE (4096)
|
||||||
|
|
||||||
|
PULONG MmGetPageEntry(PEPROCESS Process, ULONG Address);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets a page entry
|
||||||
|
* vaddr: The virtual address to set the page entry for
|
||||||
|
* attributes: The access attributes to give the page
|
||||||
|
* physaddr: The physical address the page should map to
|
||||||
|
*/
|
||||||
|
void set_page(unsigned int vaddr, unsigned int attributes,
|
||||||
|
unsigned int physaddr);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Page access attributes (or these together)
|
||||||
|
*/
|
||||||
|
#define PA_READ (1<<0)
|
||||||
|
#define PA_WRITE ((1<<0)+(1<<1))
|
||||||
|
#define PA_EXECUTE PA_READ
|
||||||
|
#define PA_PCD (1<<4)
|
||||||
|
#define PA_PWT (1<<3)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Page attributes
|
||||||
|
*/
|
||||||
|
#define PA_USER (1<<2)
|
||||||
|
#define PA_SYSTEM (0)
|
||||||
|
|
||||||
|
#define KERNEL_BASE (0xc0000000)
|
||||||
|
#define IDMAP_BASE (0xd0000000)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a linear address which can be used to access the physical memory
|
||||||
|
* starting at x
|
||||||
|
*/
|
||||||
|
extern inline unsigned int physical_to_linear(unsigned int x)
|
||||||
|
{
|
||||||
|
return(x+IDMAP_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned int linear_to_physical(unsigned int x)
|
||||||
|
{
|
||||||
|
return(x-IDMAP_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FLUSH_TLB __asm__("movl %cr3,%eax\n\tmovl %eax,%cr3\n\t")
|
||||||
|
|
||||||
|
extern inline unsigned int* get_page_directory(void)
|
||||||
|
{
|
||||||
|
unsigned int page_dir=0;
|
||||||
|
__asm__("movl %%cr3,%0\n\t"
|
||||||
|
: "=r" (page_dir));
|
||||||
|
return((unsigned int *)physical_to_linear(page_dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Amount of memory that can be mapped by a page table
|
||||||
|
*/
|
||||||
|
#define PAGE_TABLE_SIZE (4*1024*1024)
|
||||||
|
|
||||||
|
#define PAGE_MASK(x) (x&(~0xfff))
|
||||||
|
#define VADDR_TO_PT_OFFSET(x) (((x/1024)%4096))
|
||||||
|
#define VADDR_TO_PD_OFFSET(x) ((x)/(4*1024*1024))
|
||||||
|
|
||||||
|
unsigned int* get_page_entry(unsigned int vaddr);
|
||||||
|
|
||||||
|
BOOL is_page_present(unsigned int vaddr);
|
||||||
|
|
||||||
|
VOID MmSetPage(PEPROCESS Process,
|
||||||
|
PVOID Address,
|
||||||
|
ULONG flProtect,
|
||||||
|
ULONG PhysicalAddress);
|
||||||
|
|
||||||
|
|
||||||
|
VOID MmSetPageProtect(PEPROCESS Process,
|
||||||
|
PVOID Address,
|
||||||
|
ULONG flProtect);
|
||||||
|
BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address);
|
||||||
|
|
||||||
|
#endif /* __INTERNAL_HAL_PAGE_H */
|
345
reactos/include/internal/i386/segment.h
Normal file
345
reactos/include/internal/i386/segment.h
Normal file
|
@ -0,0 +1,345 @@
|
||||||
|
#ifndef _ASM_SEGMENT_H
|
||||||
|
#define _ASM_SEGMENT_H
|
||||||
|
|
||||||
|
#define USER_CS (0x8+0x3)
|
||||||
|
#define USER_DS (0x10+0x3)
|
||||||
|
#define ZERO_DS 0x18
|
||||||
|
#define KERNEL_CS 0x20
|
||||||
|
#define KERNEL_DS 0x28
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uh, these should become the main single-value transfer routines..
|
||||||
|
* They automatically use the right size if we just have the right
|
||||||
|
* pointer type..
|
||||||
|
*/
|
||||||
|
#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
|
||||||
|
#define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a silly but good way to make sure that
|
||||||
|
* the __put_user function is indeed always optimized,
|
||||||
|
* and that we use the correct sizes..
|
||||||
|
*/
|
||||||
|
extern int bad_user_access_length(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dummy pointer type structure.. gcc won't try to do something strange
|
||||||
|
* this way..
|
||||||
|
*/
|
||||||
|
struct __segment_dummy { unsigned long a[100]; };
|
||||||
|
#define __sd(x) ((struct __segment_dummy *) (x))
|
||||||
|
#define __const_sd(x) ((const struct __segment_dummy *) (x))
|
||||||
|
|
||||||
|
static inline void __put_user(unsigned long x, void * y, int size)
|
||||||
|
{
|
||||||
|
switch (size) {
|
||||||
|
case 1:
|
||||||
|
__asm__ ("movb %b1,%%fs:%0"
|
||||||
|
:"=m" (*__sd(y))
|
||||||
|
:"iq" ((unsigned char) x), "m" (*__sd(y)));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
__asm__ ("movw %w1,%%fs:%0"
|
||||||
|
:"=m" (*__sd(y))
|
||||||
|
:"ir" ((unsigned short) x), "m" (*__sd(y)));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
__asm__ ("movl %1,%%fs:%0"
|
||||||
|
:"=m" (*__sd(y))
|
||||||
|
:"ir" (x), "m" (*__sd(y)));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bad_user_access_length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long __get_user(const void * y, int size)
|
||||||
|
{
|
||||||
|
unsigned long result;
|
||||||
|
|
||||||
|
switch (size) {
|
||||||
|
case 1:
|
||||||
|
__asm__ ("movb %%fs:%1,%b0"
|
||||||
|
:"=q" (result)
|
||||||
|
:"m" (*__const_sd(y)));
|
||||||
|
return (unsigned char) result;
|
||||||
|
case 2:
|
||||||
|
__asm__ ("movw %%fs:%1,%w0"
|
||||||
|
:"=r" (result)
|
||||||
|
:"m" (*__const_sd(y)));
|
||||||
|
return (unsigned short) result;
|
||||||
|
case 4:
|
||||||
|
__asm__ ("movl %%fs:%1,%0"
|
||||||
|
:"=r" (result)
|
||||||
|
:"m" (*__const_sd(y)));
|
||||||
|
return result;
|
||||||
|
default:
|
||||||
|
return bad_user_access_length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
|
||||||
|
{
|
||||||
|
__asm__ volatile
|
||||||
|
(" cld
|
||||||
|
push %%es
|
||||||
|
push %%fs
|
||||||
|
cmpl $3,%0
|
||||||
|
pop %%es
|
||||||
|
jbe 1f
|
||||||
|
movl %%edi,%%ecx
|
||||||
|
negl %%ecx
|
||||||
|
andl $3,%%ecx
|
||||||
|
subl %%ecx,%0
|
||||||
|
rep; movsb
|
||||||
|
movl %0,%%ecx
|
||||||
|
shrl $2,%%ecx
|
||||||
|
rep; movsl
|
||||||
|
andl $3,%0
|
||||||
|
1: movl %0,%%ecx
|
||||||
|
rep; movsb
|
||||||
|
pop %%es"
|
||||||
|
:"=abd" (n)
|
||||||
|
:"0" (n),"D" ((long) to),"S" ((long) from)
|
||||||
|
:"cx","di","si");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
|
||||||
|
{
|
||||||
|
switch (n) {
|
||||||
|
case 0:
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
__put_user(*(const char *) from, (char *) to, 1);
|
||||||
|
return;
|
||||||
|
case 2:
|
||||||
|
__put_user(*(const short *) from, (short *) to, 2);
|
||||||
|
return;
|
||||||
|
case 3:
|
||||||
|
__put_user(*(const short *) from, (short *) to, 2);
|
||||||
|
__put_user(*(2+(const char *) from), 2+(char *) to, 1);
|
||||||
|
return;
|
||||||
|
case 4:
|
||||||
|
__put_user(*(const int *) from, (int *) to, 4);
|
||||||
|
return;
|
||||||
|
case 8:
|
||||||
|
__put_user(*(const int *) from, (int *) to, 4);
|
||||||
|
__put_user(*(1+(const int *) from), 1+(int *) to, 4);
|
||||||
|
return;
|
||||||
|
case 12:
|
||||||
|
__put_user(*(const int *) from, (int *) to, 4);
|
||||||
|
__put_user(*(1+(const int *) from), 1+(int *) to, 4);
|
||||||
|
__put_user(*(2+(const int *) from), 2+(int *) to, 4);
|
||||||
|
return;
|
||||||
|
case 16:
|
||||||
|
__put_user(*(const int *) from, (int *) to, 4);
|
||||||
|
__put_user(*(1+(const int *) from), 1+(int *) to, 4);
|
||||||
|
__put_user(*(2+(const int *) from), 2+(int *) to, 4);
|
||||||
|
__put_user(*(3+(const int *) from), 3+(int *) to, 4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#define COMMON(x) \
|
||||||
|
__asm__("cld\n\t" \
|
||||||
|
"push %%es\n\t" \
|
||||||
|
"push %%fs\n\t" \
|
||||||
|
"pop %%es\n\t" \
|
||||||
|
"rep ; movsl\n\t" \
|
||||||
|
x \
|
||||||
|
"pop %%es" \
|
||||||
|
: /* no outputs */ \
|
||||||
|
:"c" (n/4),"D" ((long) to),"S" ((long) from) \
|
||||||
|
:"cx","di","si")
|
||||||
|
|
||||||
|
switch (n % 4) {
|
||||||
|
case 0:
|
||||||
|
COMMON("");
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
COMMON("movsb\n\t");
|
||||||
|
return;
|
||||||
|
case 2:
|
||||||
|
COMMON("movsw\n\t");
|
||||||
|
return;
|
||||||
|
case 3:
|
||||||
|
COMMON("movsw\n\tmovsb\n\t");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#undef COMMON
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
|
||||||
|
{
|
||||||
|
__asm__ volatile
|
||||||
|
(" cld
|
||||||
|
cmpl $3,%0
|
||||||
|
jbe 1f
|
||||||
|
movl %%edi,%%ecx
|
||||||
|
negl %%ecx
|
||||||
|
andl $3,%%ecx
|
||||||
|
subl %%ecx,%0
|
||||||
|
fs; rep; movsb
|
||||||
|
movl %0,%%ecx
|
||||||
|
shrl $2,%%ecx
|
||||||
|
fs; rep; movsl
|
||||||
|
andl $3,%0
|
||||||
|
1: movl %0,%%ecx
|
||||||
|
fs; rep; movsb"
|
||||||
|
:"=abd" (n)
|
||||||
|
:"0" (n),"D" ((long) to),"S" ((long) from)
|
||||||
|
:"cx","di","si", "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
|
||||||
|
{
|
||||||
|
switch (n) {
|
||||||
|
case 0:
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
*(char *)to = __get_user((const char *) from, 1);
|
||||||
|
return;
|
||||||
|
case 2:
|
||||||
|
*(short *)to = __get_user((const short *) from, 2);
|
||||||
|
return;
|
||||||
|
case 3:
|
||||||
|
*(short *) to = __get_user((const short *) from, 2);
|
||||||
|
*((char *) to + 2) = __get_user(2+(const char *) from, 1);
|
||||||
|
return;
|
||||||
|
case 4:
|
||||||
|
*(int *) to = __get_user((const int *) from, 4);
|
||||||
|
return;
|
||||||
|
case 8:
|
||||||
|
*(int *) to = __get_user((const int *) from, 4);
|
||||||
|
*(1+(int *) to) = __get_user(1+(const int *) from, 4);
|
||||||
|
return;
|
||||||
|
case 12:
|
||||||
|
*(int *) to = __get_user((const int *) from, 4);
|
||||||
|
*(1+(int *) to) = __get_user(1+(const int *) from, 4);
|
||||||
|
*(2+(int *) to) = __get_user(2+(const int *) from, 4);
|
||||||
|
return;
|
||||||
|
case 16:
|
||||||
|
*(int *) to = __get_user((const int *) from, 4);
|
||||||
|
*(1+(int *) to) = __get_user(1+(const int *) from, 4);
|
||||||
|
*(2+(int *) to) = __get_user(2+(const int *) from, 4);
|
||||||
|
*(3+(int *) to) = __get_user(3+(const int *) from, 4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#define COMMON(x) \
|
||||||
|
__asm__("cld\n\t" \
|
||||||
|
"rep ; fs ; movsl\n\t" \
|
||||||
|
x \
|
||||||
|
: /* no outputs */ \
|
||||||
|
:"c" (n/4),"D" ((long) to),"S" ((long) from) \
|
||||||
|
:"cx","di","si","memory")
|
||||||
|
|
||||||
|
switch (n % 4) {
|
||||||
|
case 0:
|
||||||
|
COMMON("");
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
COMMON("fs ; movsb");
|
||||||
|
return;
|
||||||
|
case 2:
|
||||||
|
COMMON("fs ; movsw");
|
||||||
|
return;
|
||||||
|
case 3:
|
||||||
|
COMMON("fs ; movsw\n\tfs ; movsb");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#undef COMMON
|
||||||
|
}
|
||||||
|
|
||||||
|
#define memcpy_fromfs(to, from, n) \
|
||||||
|
(__builtin_constant_p(n) ? \
|
||||||
|
__constant_memcpy_fromfs((to),(from),(n)) : \
|
||||||
|
__generic_memcpy_fromfs((to),(from),(n)))
|
||||||
|
|
||||||
|
#define memcpy_tofs(to, from, n) \
|
||||||
|
(__builtin_constant_p(n) ? \
|
||||||
|
__constant_memcpy_tofs((to),(from),(n)) : \
|
||||||
|
__generic_memcpy_tofs((to),(from),(n)))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are deprecated..
|
||||||
|
*
|
||||||
|
* Use "put_user()" and "get_user()" with the proper pointer types instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1)
|
||||||
|
#define get_fs_word(addr) __get_user((const unsigned short *)(addr),2)
|
||||||
|
#define get_fs_long(addr) __get_user((const unsigned int *)(addr),4)
|
||||||
|
|
||||||
|
#define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1)
|
||||||
|
#define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2)
|
||||||
|
#define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4)
|
||||||
|
|
||||||
|
#ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE
|
||||||
|
|
||||||
|
static inline unsigned short get_user_word(const short *addr)
|
||||||
|
{
|
||||||
|
return __get_user(addr, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned char get_user_byte(const char * addr)
|
||||||
|
{
|
||||||
|
return __get_user(addr,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long get_user_long(const int *addr)
|
||||||
|
{
|
||||||
|
return __get_user(addr, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void put_user_byte(char val,char *addr)
|
||||||
|
{
|
||||||
|
__put_user(val, addr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void put_user_word(short val,short * addr)
|
||||||
|
{
|
||||||
|
__put_user(val, addr, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void put_user_long(unsigned long val,int * addr)
|
||||||
|
{
|
||||||
|
__put_user(val, addr, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Someone who knows GNU asm better than I should double check the following.
|
||||||
|
* It seems to work, but I don't know if I'm doing something subtly wrong.
|
||||||
|
* --- TYT, 11/24/91
|
||||||
|
* [ nothing wrong here, Linus: I just changed the ax to be any reg ]
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline unsigned long get_fs(void)
|
||||||
|
{
|
||||||
|
unsigned long _v;
|
||||||
|
__asm__("mov %%fs,%w0":"=r" (_v):"0" (0));
|
||||||
|
return _v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long get_ds(void)
|
||||||
|
{
|
||||||
|
unsigned long _v;
|
||||||
|
__asm__("mov %%ds,%w0":"=r" (_v):"0" (0));
|
||||||
|
return _v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_fs(unsigned long val)
|
||||||
|
{
|
||||||
|
__asm__ __volatile__("mov %w0,%%fs": /* no output */ :"r" (val));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_ds(unsigned long val)
|
||||||
|
{
|
||||||
|
__asm__ __volatile__("mov %w0,%%ds": /* no output */ :"r" (val));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
#endif /* _ASM_SEGMENT_H */
|
10
reactos/include/internal/mmhal.h
Normal file
10
reactos/include/internal/mmhal.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef __INCLUDE_INTERNAL_MMHAL_H
|
||||||
|
#define __INCLUDE_INTERNAL_MMHAL_H
|
||||||
|
|
||||||
|
#ifdef i386
|
||||||
|
#include <internal/i386/mmhal.h>
|
||||||
|
#else
|
||||||
|
#error "Unknown processor"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __INCLUDE_INTERNAL_MMHAL_H */
|
15
reactos/include/kernel32/kernel32.h
Normal file
15
reactos/include/kernel32/kernel32.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
void dprintf(char* fmt, ...);
|
||||||
|
void aprintf(char* fmt, ...);
|
||||||
|
|
||||||
|
#define MAGIC(c1,c2,c3,c4) ((c1) + ((c2)<<8) + ((c3)<<16) + ((c4)<<24))
|
||||||
|
|
||||||
|
#define MAGIC_HEAP MAGIC( 'H','E','A','P' )
|
||||||
|
|
||||||
|
#define ROUNDUP(a,b) ((((a)+(b)-1)/(b))*(b))
|
||||||
|
#define ROUNDDOWN(a,b) (((a)/(b))*(b))
|
||||||
|
#define FIELD_OFFSET(type,fld) ((LONG)&(((type *)0)->fld))
|
||||||
|
|
||||||
|
BOOL __ErrorReturnFalse(ULONG ErrorCode);
|
||||||
|
PVOID __ErrorReturnNull(ULONG ErrorCode);
|
5
reactos/include/ntdll/service.h
Normal file
5
reactos/include/ntdll/service.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ULONG ParametersSize;
|
||||||
|
ULONG Function;
|
||||||
|
} SERVICE_TABLE;
|
24
reactos/lib/crtdll/makefile
Normal file
24
reactos/lib/crtdll/makefile
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
all: crtdll.a
|
||||||
|
|
||||||
|
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/strlen.o string/strncat.o string/strncmp.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
|
||||||
|
|
||||||
|
|
||||||
|
STDIO_OBJECTS = stdio/vsprintf.o
|
||||||
|
|
||||||
|
STDLIB_OBJECTS = stdlib/malloc.o
|
||||||
|
|
||||||
|
OBJECTS = $(STRING_OBJECTS) $(STDIO_OBJECTS) $(STDLIB_OBJECTS)
|
||||||
|
|
||||||
|
crtdll.a: $(OBJECTS)
|
||||||
|
$(AR) vrcs crtdll.a $(OBJECTS)
|
||||||
|
|
||||||
|
dummy:
|
||||||
|
|
||||||
|
include ../../rules.mak
|
340
reactos/lib/crtdll/stdio/vsprintf.c
Normal file
340
reactos/lib/crtdll/stdio/vsprintf.c
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
/*
|
||||||
|
* 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 <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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
31
reactos/lib/crtdll/stdlib/malloc.c
Normal file
31
reactos/lib/crtdll/stdlib/malloc.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
void* malloc(size_t size)
|
||||||
|
{
|
||||||
|
return(HeapAlloc(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void* ptr)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* calloc(size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
return(HeapAlloc(GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
nmemb*size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void* realloc(void* ptr, size_t size)
|
||||||
|
{
|
||||||
|
return(HeapReAlloc(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
ptr,
|
||||||
|
size));
|
||||||
|
}
|
17
reactos/lib/crtdll/string/memchr.c
Normal file
17
reactos/lib/crtdll/string/memchr.c
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
if (n)
|
||||||
|
{
|
||||||
|
const char *p = s;
|
||||||
|
do {
|
||||||
|
if (*p++ == c)
|
||||||
|
return unconst(p-1, void *);
|
||||||
|
} while (--n != 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
17
reactos/lib/crtdll/string/memcmp.c
Normal file
17
reactos/lib/crtdll/string/memcmp.c
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
memcmp(const void *s1, const void *s2, size_t n)
|
||||||
|
{
|
||||||
|
if (n != 0)
|
||||||
|
{
|
||||||
|
const unsigned char *p1 = s1, *p2 = s2;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (*p1++ != *p2++)
|
||||||
|
return (*--p1 - *--p2);
|
||||||
|
} while (--n != 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
20
reactos/lib/crtdll/string/memcpy.s
Normal file
20
reactos/lib/crtdll/string/memcpy.s
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
|
||||||
|
.file "memcpy.s"
|
||||||
|
.text
|
||||||
|
.align 4
|
||||||
|
.globl _memcpy
|
||||||
|
_memcpy:
|
||||||
|
pushl %ebp
|
||||||
|
movl %esp,%ebp
|
||||||
|
pushl %esi
|
||||||
|
pushl %edi
|
||||||
|
movl 8(%ebp),%edi
|
||||||
|
movl 12(%ebp),%esi
|
||||||
|
movl 16(%ebp),%ecx
|
||||||
|
call ___dj_movedata
|
||||||
|
popl %edi
|
||||||
|
popl %esi
|
||||||
|
movl 8(%ebp),%eax
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
|
33
reactos/lib/crtdll/string/memmove.s
Normal file
33
reactos/lib/crtdll/string/memmove.s
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
|
||||||
|
.file "memmove.s"
|
||||||
|
.globl _memmove
|
||||||
|
_memmove:
|
||||||
|
pushl %ebp
|
||||||
|
movl %esp,%ebp
|
||||||
|
pushl %esi
|
||||||
|
pushl %edi
|
||||||
|
movl 8(%ebp),%edi
|
||||||
|
movl 12(%ebp),%esi
|
||||||
|
movl 16(%ebp),%ecx
|
||||||
|
jecxz L2
|
||||||
|
cld
|
||||||
|
cmpl %esi,%edi
|
||||||
|
jb L3
|
||||||
|
|
||||||
|
std
|
||||||
|
addl %ecx,%esi
|
||||||
|
addl %ecx,%edi
|
||||||
|
decl %esi
|
||||||
|
decl %edi
|
||||||
|
L3:
|
||||||
|
rep
|
||||||
|
movsb
|
||||||
|
|
||||||
|
L2:
|
||||||
|
cld
|
||||||
|
popl %edi
|
||||||
|
popl %esi
|
||||||
|
movl 8(%ebp),%eax
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
|
51
reactos/lib/crtdll/string/memset.s
Normal file
51
reactos/lib/crtdll/string/memset.s
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
|
||||||
|
.file "memset.s"
|
||||||
|
.text
|
||||||
|
.align 4
|
||||||
|
.globl _memset
|
||||||
|
_memset:
|
||||||
|
pushl %ebp
|
||||||
|
movl %esp,%ebp
|
||||||
|
pushl %edi
|
||||||
|
movl 8(%ebp),%edi
|
||||||
|
movl 12(%ebp),%eax
|
||||||
|
movl 16(%ebp),%ecx
|
||||||
|
cld
|
||||||
|
|
||||||
|
# We will handle memsets of <= 15 bytes one byte at a time.
|
||||||
|
# This avoids some extra overhead for small memsets, and
|
||||||
|
# knowing we are setting > 15 bytes eliminates some annoying
|
||||||
|
# checks in the "long move" case.
|
||||||
|
cmpl $15,%ecx
|
||||||
|
jle L3
|
||||||
|
|
||||||
|
# Otherwise, tile the byte value out into %eax.
|
||||||
|
# 0x41 -> 0x41414141, etc.
|
||||||
|
movb %al,%ah
|
||||||
|
movl %eax,%edx
|
||||||
|
sall $16,%eax
|
||||||
|
movw %dx,%ax
|
||||||
|
jmp L2
|
||||||
|
|
||||||
|
# Handle any cruft necessary to get %edi long-aligned.
|
||||||
|
L1: stosb
|
||||||
|
decl %ecx
|
||||||
|
L2: testl $3,%edi
|
||||||
|
jnz L1
|
||||||
|
|
||||||
|
# Now slam out all of the longs.
|
||||||
|
movl %ecx,%edx
|
||||||
|
shrl $2,%ecx
|
||||||
|
rep
|
||||||
|
stosl
|
||||||
|
|
||||||
|
# Finally, handle any trailing cruft. We know the high three bytes
|
||||||
|
# of %ecx must be zero, so just put the "slop count" in the low byte.
|
||||||
|
movb %dl,%cl
|
||||||
|
andb $3,%cl
|
||||||
|
L3: rep
|
||||||
|
stosb
|
||||||
|
popl %edi
|
||||||
|
movl 8(%ebp),%eax
|
||||||
|
leave
|
||||||
|
ret
|
12
reactos/lib/crtdll/string/strcat.c
Normal file
12
reactos/lib/crtdll/string/strcat.c
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
strcat(char *s, const char *append)
|
||||||
|
{
|
||||||
|
char *save = s;
|
||||||
|
|
||||||
|
for (; *s; ++s);
|
||||||
|
while ((*s++ = *append++));
|
||||||
|
return save;
|
||||||
|
}
|
20
reactos/lib/crtdll/string/strchr.c
Normal file
20
reactos/lib/crtdll/string/strchr.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/* 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 cc = c;
|
||||||
|
while (*s)
|
||||||
|
{
|
||||||
|
if (*s == cc)
|
||||||
|
return unconst(s, char *);
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
if (cc == 0)
|
||||||
|
return unconst(s, char *);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
15
reactos/lib/crtdll/string/strcmp.c
Normal file
15
reactos/lib/crtdll/string/strcmp.c
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
strcmp(const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
while (*s1 == *s2)
|
||||||
|
{
|
||||||
|
if (*s1 == 0)
|
||||||
|
return 0;
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
}
|
||||||
|
return *(unsigned const char *)s1 - *(unsigned const char *)(s2);
|
||||||
|
}
|
8
reactos/lib/crtdll/string/strcoll.c
Normal file
8
reactos/lib/crtdll/string/strcoll.c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
strcoll(const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
return strcmp(s1, s2);
|
||||||
|
}
|
11
reactos/lib/crtdll/string/strcpy.c
Normal file
11
reactos/lib/crtdll/string/strcpy.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
strcpy(char *to, const char *from)
|
||||||
|
{
|
||||||
|
char *save = to;
|
||||||
|
|
||||||
|
for (; (*to = *from); ++from, ++to);
|
||||||
|
return save;
|
||||||
|
}
|
20
reactos/lib/crtdll/string/strcspn.c
Normal file
20
reactos/lib/crtdll/string/strcspn.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
size_t
|
||||||
|
strcspn(const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
const char *p, *spanp;
|
||||||
|
char c, sc;
|
||||||
|
|
||||||
|
for (p = s1;;)
|
||||||
|
{
|
||||||
|
c = *p++;
|
||||||
|
spanp = s2;
|
||||||
|
do {
|
||||||
|
if ((sc = *spanp++) == c)
|
||||||
|
return p - 1 - s1;
|
||||||
|
} while (sc != 0);
|
||||||
|
}
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
16
reactos/lib/crtdll/string/strdup.c
Normal file
16
reactos/lib/crtdll/string/strdup.c
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
|
||||||
|
#include <string.h>
|
||||||
|
//#include <stdlib.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
strdup(const char *_s)
|
||||||
|
{
|
||||||
|
char *rv;
|
||||||
|
if (_s == 0)
|
||||||
|
return 0;
|
||||||
|
rv = (char *)malloc(strlen(_s) + 1);
|
||||||
|
if (rv == 0)
|
||||||
|
return 0;
|
||||||
|
strcpy(rv, _s);
|
||||||
|
return rv;
|
||||||
|
}
|
14
reactos/lib/crtdll/string/strlen.c
Normal file
14
reactos/lib/crtdll/string/strlen.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
size_t
|
||||||
|
strlen(const char *str)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
if (str == 0)
|
||||||
|
return 0;
|
||||||
|
for (s = str; *s; ++s);
|
||||||
|
return s-str;
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue