Initial revision

svn path=/trunk/; revision=50
This commit is contained in:
Rex Jolliff 1998-10-05 04:00:59 +00:00
parent 5c0fb0f108
commit 645218d5c8
160 changed files with 18523 additions and 0 deletions

21
reactos/DIRS Normal file
View 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
View 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
View 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
View 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

View file

@ -0,0 +1,11 @@
extern void main(void);
void start(void)
{
main();
for(;;);
}
void __main(void)
{
}

View 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

View 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

View 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;
}

View 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

View 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

View 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);
}
}

View 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
View 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

View file

@ -0,0 +1,2 @@
DIRS=exe \
sys

View 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

View 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

View file

@ -0,0 +1,10 @@
TARGETNAME=event
TARGETPATH=$(BASEDIR)\lib
TARGETTYPE=PROGRAM
INCLUDES=..\sys
SOURCES=eventtest.c
UMTYPE=console
UMBASE=0x100000

View 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

View 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

View 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__

View 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

View 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"

View 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

View 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

File diff suppressed because it is too large Load diff

View 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 */

View 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)

View file

@ -0,0 +1,11 @@
#
#
#
all: ide.o
ide.o: ide.c ide.h idep.h partitio.h
dummy:
include ../../../rules.mak

View 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

View 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);
}

View 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

View file

@ -0,0 +1 @@
all: keyboard.o

View file

@ -0,0 +1 @@
all: mouse.o

View 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);
};

View file

@ -0,0 +1 @@
all: null.o

View 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);
}

View file

@ -0,0 +1 @@
all: parallel.o

View 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);
}

View 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

View file

@ -0,0 +1,4 @@
all: sdisk.o
WIN32_LEAN_AND_MEAN = yes
include ../../../rules.mak

View 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);
}

View file

@ -0,0 +1 @@
all: serial.o

View 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);
};

View 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);
}

View 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);

View file

@ -0,0 +1,2 @@
sound.o: sound.c dsp.c mixer.c wave.h wave.c
all: sound.o

View 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;
}

View 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);

View file

@ -0,0 +1,9 @@
typedef struct
{
unsigned short base;
unsigned char irq;
unsigned char dma8;
unsigned char dma16;
unsigned char* buffer;
}SB16;

View file

@ -0,0 +1,3 @@
void write_wave()
{
}

View 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"

View 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);

View file

@ -0,0 +1 @@
all: test.o

View 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);
}

View file

@ -0,0 +1 @@
all: test.o

View 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);
}

View 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);
}

View 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,&current_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,&current_dir,current);
}
if (next==NULL && current_ino!=0)
{
MinixReadInode(DeviceObject,DeviceExt,current_ino,&current_dir);
}
else
{
(*Information) = FILE_DOES_NOT_EXIST;
return(STATUS_UNSUCCESSFUL);
}
memcpy(result,&current_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);
}

View 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);
}

View 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);

View 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

View 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);
}

View 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);
}

View file

@ -0,0 +1,2 @@
all: template.o
$(LD) -r template.o -o tfsd.o

View 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);
}

View 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,
&sectorNumber,
&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;
}

View 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);
}

View 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

View 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

Binary file not shown.

View 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);
}

View 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

View 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

View 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);

View 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 */

View 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 */

View 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);

View 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

View 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

View 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 */

View 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 */

View 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 */

View 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);

View file

@ -0,0 +1,5 @@
typedef struct
{
ULONG ParametersSize;
ULONG Function;
} SERVICE_TABLE;

View 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

View 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;
}

View 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));
}

View 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;
}

View 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;
}

View 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

View 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

View 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

View 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;
}

View 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;
}

View 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);
}

View 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);
}

View 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;
}

View 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 */
}

View 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;
}

View 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