From e8ecaa9aa148d5bd99a46dde1203de9811a68879 Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Sat, 6 Dec 2003 17:15:38 +0000 Subject: [PATCH] basic support to display NTFS streams in winefile windows svn path=/trunk/; revision=6865 --- reactos/subsys/system/explorer/buildno.h | 8 +- reactos/subsys/system/explorer/doc/TODO.txt | 1 + .../subsys/system/explorer/doc/changes.txt | 1 + .../subsys/system/explorer/doxy-footer.html | 2 +- .../subsys/system/explorer/i386-stub-win32.c | 984 +++++++++--------- .../system/explorer/shell/filechild.cpp | 7 +- reactos/subsys/system/explorer/shell/pane.cpp | 10 +- .../subsys/system/explorer/shell/winfs.cpp | 88 +- .../system/explorer/utility/shellclasses.h | 3 +- .../subsys/system/explorer/utility/utility.h | 5 + 10 files changed, 605 insertions(+), 504 deletions(-) diff --git a/reactos/subsys/system/explorer/buildno.h b/reactos/subsys/system/explorer/buildno.h index 25196adecb0..0c95067424f 100644 --- a/reactos/subsys/system/explorer/buildno.h +++ b/reactos/subsys/system/explorer/buildno.h @@ -1,10 +1,10 @@ /* Do not edit - Machine generated */ #ifndef _INC_REACTOS_BUILDNO #define _INC_REACTOS_BUILDNO -#define KERNEL_VERSION_BUILD 0 -#define KERNEL_VERSION_BUILD_STR "0" -#define KERNEL_RELEASE_RC "0.1.5.0\0" -#define KERNEL_RELEASE_STR "0.1.5.0" +#define KERNEL_VERSION_BUILD 11 +#define KERNEL_VERSION_BUILD_STR "11" +#define KERNEL_RELEASE_RC "0.1.5.11\0" +#define KERNEL_RELEASE_STR "0.1.5.11" #define KERNEL_VERSION_RC "0.1.5\0" #define KERNEL_VERSION_STR "0.1.5" #endif diff --git a/reactos/subsys/system/explorer/doc/TODO.txt b/reactos/subsys/system/explorer/doc/TODO.txt index 8b4c22acaca..438f750f26f 100644 --- a/reactos/subsys/system/explorer/doc/TODO.txt +++ b/reactos/subsys/system/explorer/doc/TODO.txt @@ -14,6 +14,7 @@ - Application Desktop Toolbars - desktop switching - command line in explorer windows +- hide CVS subdirectories, may be even implement a CVS managment plugin - printer and RAS connection icons in desktop notification area - make task buttons smaller when running many applications - use multi threading for launching of programs and filling start menu subdirectories diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index 77374844cc5..0aae7a4fdeb 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -47,3 +47,4 @@ If you search for more information, look into the CVS repository. 18.10.2003 m. fuchs Program search dialog with interactive filtering and sorting does now work. 19.10.2003 m. fuchs implemented floating start menus 29.11.2003 m. fuchs implemented GDB stub for remote debugging +06.12.2003 m. fuchs basic support to display NTFS streams in winefile windows diff --git a/reactos/subsys/system/explorer/doxy-footer.html b/reactos/subsys/system/explorer/doxy-footer.html index b78fab6bd07..237d894c3a0 100644 --- a/reactos/subsys/system/explorer/doxy-footer.html +++ b/reactos/subsys/system/explorer/doxy-footer.html @@ -3,7 +3,7 @@
ROS Explore Source Code Documentation -
generated on 26.11.2003 by +
generated on 06.12.2003 by
doxygen
diff --git a/reactos/subsys/system/explorer/i386-stub-win32.c b/reactos/subsys/system/explorer/i386-stub-win32.c index 89131e726b8..2fa2d56643f 100644 --- a/reactos/subsys/system/explorer/i386-stub-win32.c +++ b/reactos/subsys/system/explorer/i386-stub-win32.c @@ -1,6 +1,6 @@ /**************************************************************************** - THIS SOFTWARE IS NOT COPYRIGHTED + THIS SOFTWARE IS NOT COPYRIGHTED HP offers the following for use in the public domain. HP makes no warranty with regard to the software or it's performance and the @@ -13,62 +13,62 @@ ****************************************************************************/ /**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ + * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ + * Module name: remcom.c $ + * Revision: 1.34 $ + * Date: 91/03/09 12:29:49 $ + * Contributor: Lake Stevens Instrument Division$ * - * Description: low level support for gdb debugger. $ + * Description: low level support for gdb debugger. $ * - * Considerations: only works on target hardware $ + * Considerations: only works on target hardware $ * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ + * Written by: Glenn Engel $ + * ModuleState: Experimental $ * - * NOTES: See Below $ + * NOTES: See Below $ * - * Modified for 386 by Jim Kingdon, Cygnus Support. + * Modified for 386 by Jim Kingdon, Cygnus Support. * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. + * To enable debugger support, two things need to happen. One, a + * call to set_debug_traps() is necessary in order to allow any breakpoints + * or error conditions to be properly intercepted and reported to gdb. + * Two, a breakpoint needs to be generated to begin communication. This + * is most easily accomplished by a call to breakpoint(). Breakpoint() + * simulates a breakpoint by executing a trap #1. * - * The external function exceptionHandler() is - * used to attach a specific handler to a specific 386 vector number. - * It should use the same privilege level it runs at. It should - * install it as an interrupt gate so that interrupts are masked - * while the handler runs. + * The external function exceptionHandler() is + * used to attach a specific handler to a specific 386 vector number. + * It should use the same privilege level it runs at. It should + * install it as an interrupt gate so that interrupts are masked + * while the handler runs. * - * Because gdb will sometimes write to the stack area to execute function - * calls, this program cannot rely on using the supervisor stack so it - * uses it's own stack area reserved in the int array remcomStack. + * Because gdb will sometimes write to the stack area to execute function + * calls, this program cannot rely on using the supervisor stack so it + * uses it's own stack area reserved in the int array remcomStack. * ************* * - * The following gdb commands are supported: + * The following gdb commands are supported: * - * command function Return value + * command function Return value * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN + * g return the value of the CPU registers hex data or ENN + * G set the value of the CPU registers OK or ENN * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN + * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN + * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN + * c Resume at current address SNN ( signal NN) + * cAA..AA Continue at address AA..AA SNN * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN + * s Step one instruction SNN + * sAA..AA Step one instruction from AA..AA SNN * - * k kill + * k kill * - * ? What was the last sigval ? SNN (signal NN) + * ? What was the last sigval ? SNN (signal NN) * * All commands and responses are sent with a packet which includes a * checksum. A packet consists of @@ -77,15 +77,15 @@ * * where * :: - * :: < two hex digits computed as modulo 256 sum of > + * :: < two hex digits computed as modulo 256 sum of > * * When a packet is received, it is first acknowledged with either '+' or '-'. * '+' indicates a successful transfer. '-' indicates a failed transfer. * * Example: * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 + * Host: Reply: + * $m0,10#2a +$00010203040506070809101112131415#42 * ****************************************************************************/ @@ -97,9 +97,9 @@ * external low-level support routines */ -extern void putDebugChar(); /* write a single character */ -extern int getDebugChar(); /* read and return a single char */ -extern void exceptionHandler(); /* assign an exception handler */ +extern void putDebugChar(); /* write a single character */ +extern int getDebugChar(); /* read and return a single char */ +extern void exceptionHandler(); /* assign an exception handler */ /************************************************************************/ /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ @@ -108,21 +108,21 @@ extern void exceptionHandler(); /* assign an exception handler */ static char initialized; /* boolean flag. != 0 means we've been initialized */ -int remote_debug; -/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ +int remote_debug; +/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ static const char hexchars[]="0123456789abcdef"; /* Number of registers. */ -#define NUMREGS 16 +#define NUMREGS 16 /* Number of bytes of registers. */ #define NUMREGBYTES (NUMREGS * 4) enum regnames {EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, - PC /* also known as eip */, - PS /* also known as eflags */, - CS, SS, DS, ES, FS, GS}; + PC /* also known as eip */, + PS /* also known as eflags */, + CS, SS, DS, ES, FS, GS}; /* * these should not be static cuz they can be used outside this module @@ -136,7 +136,7 @@ int remcomStack[STACKSIZE/sizeof(int)]; static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; /*************************** ASSEMBLY CODE MACROS *************************/ -/* */ +/* */ extern void return_to_prog (); @@ -160,14 +160,14 @@ asm(" movw _registers+52, %es"); asm(" movw _registers+56, %fs"); asm(" movw _registers+60, %gs"); asm(" movl _registers+36, %eax"); -asm(" pushl %eax"); /* saved eflags */ +asm(" pushl %eax"); /* saved eflags */ asm(" movl _registers+40, %eax"); -asm(" pushl %eax"); /* saved cs */ +asm(" pushl %eax"); /* saved cs */ asm(" movl _registers+32, %eax"); -asm(" pushl %eax"); /* saved eip */ +asm(" pushl %eax"); /* saved eip */ asm(" movl _registers, %eax"); -asm("ret"); //MF +asm("ret"); //MF /* use iret to restore pc and flags together so that trace flag works right. */ @@ -185,43 +185,43 @@ int gdb_i386errcode; int gdb_i386vector = -1; /* GDB stores segment registers in 32-bit words (that's just the way - m-i386v.h is written). So zero the appropriate areas in registers. */ + m-i386v.h is written). So zero the appropriate areas in registers. */ #define SAVE_REGISTERS1() \ - asm ("movl %eax, _registers"); \ - asm ("movl %ecx, _registers+4"); \ - asm ("movl %edx, _registers+8"); \ - asm ("movl %ebx, _registers+12"); \ - asm ("movl %ebp, _registers+20"); \ - asm ("movl %esi, _registers+24"); \ - asm ("movl %edi, _registers+28"); \ - asm ("movw $0, %ax"); \ - asm ("movw %ds, _registers+48"); \ - asm ("movw %ax, _registers+50"); \ - asm ("movw %es, _registers+52"); \ - asm ("movw %ax, _registers+54"); \ - asm ("movw %fs, _registers+56"); \ - asm ("movw %ax, _registers+58"); \ - asm ("movw %gs, _registers+60"); \ + asm ("movl %eax, _registers"); \ + asm ("movl %ecx, _registers+4"); \ + asm ("movl %edx, _registers+8"); \ + asm ("movl %ebx, _registers+12"); \ + asm ("movl %ebp, _registers+20"); \ + asm ("movl %esi, _registers+24"); \ + asm ("movl %edi, _registers+28"); \ + asm ("movw $0, %ax"); \ + asm ("movw %ds, _registers+48"); \ + asm ("movw %ax, _registers+50"); \ + asm ("movw %es, _registers+52"); \ + asm ("movw %ax, _registers+54"); \ + asm ("movw %fs, _registers+56"); \ + asm ("movw %ax, _registers+58"); \ + asm ("movw %gs, _registers+60"); \ asm ("movw %ax, _registers+62"); #define SAVE_ERRCODE() \ - asm ("popl %ebx"); \ + asm ("popl %ebx"); \ asm ("movl %ebx, _gdb_i386errcode"); #define SAVE_REGISTERS2() \ - asm ("popl %ebx"); /* old eip */ \ - asm ("movl %ebx, _registers+32"); \ - asm ("popl %ebx"); /* old cs */ \ - asm ("movl %ebx, _registers+40"); \ - asm ("movw %ax, _registers+42"); \ - asm ("popl %ebx"); /* old eflags */ \ - asm ("movl %ebx, _registers+36"); \ + asm ("popl %ebx"); /* old eip */ \ + asm ("movl %ebx, _registers+32"); \ + asm ("popl %ebx"); /* old cs */ \ + asm ("movl %ebx, _registers+40"); \ + asm ("movw %ax, _registers+42"); \ + asm ("popl %ebx"); /* old eflags */ \ + asm ("movl %ebx, _registers+36"); \ /* Now that we've done the pops, we can save the stack pointer."); */ \ - asm ("movw %ss, _registers+44"); \ - asm ("movw %ax, _registers+46"); \ + asm ("movw %ss, _registers+44"); \ + asm ("movw %ax, _registers+46"); \ asm ("movl %esp, _registers+16"); /* See if mem_fault_routine is set, if so just IRET to that address. */ #define CHECK_FAULT() \ - asm ("cmpl $0, _mem_fault_routine"); \ + asm ("cmpl $0, _mem_fault_routine"); \ asm ("jne mem_fault"); asm (".text"); @@ -243,12 +243,12 @@ asm (" popl %edx"); /* eflags */ would after a "call" instruction. */ asm (" leave"); -/* Push the stuff that iret wants. */ +/* Push the stuff that iret wants. */ asm (" pushl %edx"); /* eflags */ asm (" pushl %ecx"); /* cs */ asm (" pushl %eax"); /* eip */ -/* Zero mem_fault_routine. */ +/* Zero mem_fault_routine. */ asm (" movl $0, %eax"); asm (" movl %eax, _mem_fault_routine"); @@ -261,10 +261,10 @@ asm ("iret"); * all the cpu regs in the _registers array, munges the stack a bit, * and invokes an exception handler (remcom_handler). * - * stack on entry: stack on exit: - * old eflags vector number - * old cs (zero-filled to 32 bits) - * old eip + * stack on entry: stack on exit: + * old eflags vector number + * old cs (zero-filled to 32 bits) + * old eip * */ extern void _catchException3(); @@ -276,7 +276,7 @@ SAVE_REGISTERS2(); asm ("pushl $3"); CALL_HOOK(); -/* Same thing for exception 1. */ +/* Same thing for exception 1. */ extern void _catchException1(); asm(".text"); asm(".globl __catchException1"); @@ -286,7 +286,7 @@ SAVE_REGISTERS2(); asm ("pushl $1"); CALL_HOOK(); -/* Same thing for exception 0. */ +/* Same thing for exception 0. */ extern void _catchException0(); asm(".text"); asm(".globl __catchException0"); @@ -296,7 +296,7 @@ SAVE_REGISTERS2(); asm ("pushl $0"); CALL_HOOK(); -/* Same thing for exception 4. */ +/* Same thing for exception 4. */ extern void _catchException4(); asm(".text"); asm(".globl __catchException4"); @@ -306,7 +306,7 @@ SAVE_REGISTERS2(); asm ("pushl $4"); CALL_HOOK(); -/* Same thing for exception 5. */ +/* Same thing for exception 5. */ extern void _catchException5(); asm(".text"); asm(".globl __catchException5"); @@ -316,7 +316,7 @@ SAVE_REGISTERS2(); asm ("pushl $5"); CALL_HOOK(); -/* Same thing for exception 6. */ +/* Same thing for exception 6. */ extern void _catchException6(); asm(".text"); asm(".globl __catchException6"); @@ -326,7 +326,7 @@ SAVE_REGISTERS2(); asm ("pushl $6"); CALL_HOOK(); -/* Same thing for exception 7. */ +/* Same thing for exception 7. */ extern void _catchException7(); asm(".text"); asm(".globl __catchException7"); @@ -336,7 +336,7 @@ SAVE_REGISTERS2(); asm ("pushl $7"); CALL_HOOK(); -/* Same thing for exception 8. */ +/* Same thing for exception 8. */ extern void _catchException8(); asm(".text"); asm(".globl __catchException8"); @@ -347,7 +347,7 @@ SAVE_REGISTERS2(); asm ("pushl $8"); CALL_HOOK(); -/* Same thing for exception 9. */ +/* Same thing for exception 9. */ extern void _catchException9(); asm(".text"); asm(".globl __catchException9"); @@ -432,11 +432,11 @@ CALL_HOOK(); * stack pointer into an area reserved for debugger use. */ asm("_remcomHandler:"); -asm(" popl %eax"); /* pop off return address */ -asm(" popl %eax"); /* get the exception number */ +asm(" popl %eax"); /* pop off return address */ +asm(" popl %eax"); /* get the exception number */ asm(" movl _stackPtr, %esp"); /* move to remcom stack area */ -asm(" pushl %eax"); /* push exception onto stack */ -asm(" call _handle_exception"); /* this never returns */ +asm(" pushl %eax"); /* push exception onto stack */ +asm(" call _handle_exception"); /* this never returns */ void @@ -448,7 +448,7 @@ _returnFromException () #endif // !WIN32 -#ifdef _MSC_VER //MF +#ifdef _MSC_VER //MF #define BREAKPOINT() __asm int 3; #else #define BREAKPOINT() asm(" int $3"); @@ -508,21 +508,21 @@ void win32_exception_handler(EXCEPTION_POINTERS* exc_info) int hex (ch) - char ch; + char ch; { if ((ch >= 'a') && (ch <= 'f')) - return (ch - 'a' + 10); + return (ch - 'a' + 10); if ((ch >= '0') && (ch <= '9')) - return (ch - '0'); + return (ch - '0'); if ((ch >= 'A') && (ch <= 'F')) - return (ch - 'A' + 10); + return (ch - 'A' + 10); return (-1); } static char remcomInBuffer[BUFMAX]; static char remcomOutBuffer[BUFMAX]; -/* scan for the sequence $# */ +/* scan for the sequence $# */ unsigned char * getpacket (void) @@ -534,64 +534,64 @@ getpacket (void) char ch; while (1) - { - /* wait around for the start character, ignore all other characters */ - while ((ch = getDebugChar ()) != '$') - ; - - retry: - checksum = 0; - xmitcsum = -1; - count = 0; - - /* now, read until a # or end of buffer is found */ - while (count < BUFMAX) { - ch = getDebugChar (); - if (ch == '$') - goto retry; + /* wait around for the start character, ignore all other characters */ + while ((ch = getDebugChar ()) != '$') + ; + + retry: + checksum = 0; + xmitcsum = -1; + count = 0; + + /* now, read until a # or end of buffer is found */ + while (count < BUFMAX) + { + ch = getDebugChar (); + if (ch == '$') + goto retry; + if (ch == '#') + break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + buffer[count] = 0; + if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') - { - ch = getDebugChar (); - xmitcsum = hex (ch) << 4; - ch = getDebugChar (); - xmitcsum += hex (ch); - - if (checksum != xmitcsum) - { - if (remote_debug) { - fprintf (stderr, - "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", - checksum, xmitcsum, buffer); + ch = getDebugChar (); + xmitcsum = hex (ch) << 4; + ch = getDebugChar (); + xmitcsum += hex (ch); + + if (checksum != xmitcsum) + { + if (remote_debug) + { + fprintf (stderr, + "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", + checksum, xmitcsum, buffer); + } + putDebugChar ('-'); /* failed checksum */ + } + else + { + putDebugChar ('+'); /* successful transfer */ + + /* if a sequence char is present, reply the sequence ID */ + if (buffer[2] == ':') + { + putDebugChar (buffer[0]); + putDebugChar (buffer[1]); + + return &buffer[3]; + } + + return &buffer[0]; + } } - putDebugChar ('-'); /* failed checksum */ - } - else - { - putDebugChar ('+'); /* successful transfer */ - - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') - { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - return &buffer[3]; - } - - return &buffer[0]; - } } - } } /* send the packet in buffer. */ @@ -605,33 +605,33 @@ putpacket (unsigned char *buffer) /* $#. */ do - { - putDebugChar ('$'); - checksum = 0; - count = 0; - - while ((ch = buffer[count]) != 0) { - putDebugChar (ch); - checksum += ch; - count += 1; + putDebugChar ('$'); + checksum = 0; + count = 0; + + while ((ch = buffer[count]) != 0) + { + putDebugChar (ch); + checksum += ch; + count += 1; + } + + putDebugChar ('#'); + putDebugChar (hexchars[checksum >> 4]); + putDebugChar (hexchars[checksum % 16]); + } - - putDebugChar ('#'); - putDebugChar (hexchars[checksum >> 4]); - putDebugChar (hexchars[checksum % 16]); - - } while (getDebugChar () != '+'); } void debug_error (format, parm) - char *format; - char *parm; + char *format; + char *parm; { if (remote_debug) - fprintf (stderr, format, parm); + fprintf (stderr, format, parm); } /* Address of a routine to RTE to if we get a memory fault. */ @@ -650,7 +650,7 @@ set_mem_err (void) /* These are separate functions so that they are so short and sweet that the compiler won't save any registers (if there is a fault to mem_fault, they won't get restored, so there better not be any - saved). */ + saved). */ int get_char (char *addr) { @@ -669,33 +669,33 @@ set_char (char *addr, int val) a fault; if zero treat a fault like any other fault in the stub. */ char * mem2hex (mem, buf, count, may_fault) - char *mem; - char *buf; - int count; - int may_fault; + char *mem; + char *buf; + int count; + int may_fault; { int i; unsigned char ch; #ifdef WIN32 //MF if (IsBadReadPtr(mem, count)) - return mem; + return mem; #else if (may_fault) - mem_fault_routine = set_mem_err; + mem_fault_routine = set_mem_err; #endif for (i = 0; i < count; i++) - { - ch = get_char (mem++); - if (may_fault && mem_err) - return (buf); - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch % 16]; - } + { + ch = get_char (mem++); + if (may_fault && mem_err) + return (buf); + *buf++ = hexchars[ch >> 4]; + *buf++ = hexchars[ch % 16]; + } *buf = 0; #ifndef WIN32 //MF if (may_fault) - mem_fault_routine = NULL; + mem_fault_routine = NULL; #endif return (buf); } @@ -704,10 +704,10 @@ mem2hex (mem, buf, count, may_fault) /* return a pointer to the character AFTER the last byte written */ char * hex2mem (buf, mem, count, may_fault) - char *buf; - char *mem; - int count; - int may_fault; + char *buf; + char *mem; + int count; + int may_fault; { int i; unsigned char ch; @@ -720,21 +720,21 @@ hex2mem (buf, mem, count, may_fault) VirtualProtect(mem, count, PAGE_EXECUTE_READWRITE, &old_protect); #else if (may_fault) - mem_fault_routine = set_mem_err; + mem_fault_routine = set_mem_err; #endif for (i = 0; i < count; i++) - { - ch = hex (*buf++) << 4; - ch = ch + hex (*buf++); - set_char (mem++, ch); - if (may_fault && mem_err) - return (mem); - } + { + ch = hex (*buf++) << 4; + ch = ch + hex (*buf++); + set_char (mem++, ch); + if (may_fault && mem_err) + return (mem); + } #ifndef WIN32 //MF if (may_fault) - mem_fault_routine = NULL; + mem_fault_routine = NULL; #endif return (mem); @@ -747,61 +747,61 @@ computeSignal (int exceptionVector) { int sigval; switch (exceptionVector) - { - case 0: - sigval = 8; - break; /* divide by zero */ - case 1: - sigval = 5; - break; /* debug exception */ - case 3: - sigval = 5; - break; /* breakpoint */ - case 4: - sigval = 16; - break; /* into instruction (overflow) */ - case 5: - sigval = 16; - break; /* bound instruction */ - case 6: - sigval = 4; - break; /* Invalid opcode */ - case 7: - sigval = 8; - break; /* coprocessor not available */ - case 8: - sigval = 7; - break; /* double fault */ - case 9: - sigval = 11; - break; /* coprocessor segment overrun */ - case 10: - sigval = 11; - break; /* Invalid TSS */ - case 11: - sigval = 11; - break; /* Segment not present */ - case 12: - sigval = 11; - break; /* stack exception */ - case 13: - sigval = 11; - break; /* general protection */ - case 14: - sigval = 11; - break; /* page fault */ - case 16: - sigval = 7; - break; /* coprocessor error */ - default: - sigval = 7; /* "software generated" */ - } + { + case 0: + sigval = 8; + break; /* divide by zero */ + case 1: + sigval = 5; + break; /* debug exception */ + case 3: + sigval = 5; + break; /* breakpoint */ + case 4: + sigval = 16; + break; /* into instruction (overflow) */ + case 5: + sigval = 16; + break; /* bound instruction */ + case 6: + sigval = 4; + break; /* Invalid opcode */ + case 7: + sigval = 8; + break; /* coprocessor not available */ + case 8: + sigval = 7; + break; /* double fault */ + case 9: + sigval = 11; + break; /* coprocessor segment overrun */ + case 10: + sigval = 11; + break; /* Invalid TSS */ + case 11: + sigval = 11; + break; /* Segment not present */ + case 12: + sigval = 11; + break; /* stack exception */ + case 13: + sigval = 11; + break; /* general protection */ + case 14: + sigval = 11; + break; /* page fault */ + case 16: + sigval = 7; + break; /* coprocessor error */ + default: + sigval = 7; /* "software generated" */ + } return (sigval); } /**********************************************/ /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */ -/* RETURN NUMBER OF CHARS PROCESSED */ +/* RETURN NUMBER OF CHARS PROCESSED */ /**********************************************/ int hexToInt (char **ptr, int *intValue) @@ -812,18 +812,18 @@ hexToInt (char **ptr, int *intValue) *intValue = 0; while (**ptr) - { - hexValue = hex (**ptr); - if (hexValue >= 0) { - *intValue = (*intValue << 4) | hexValue; - numChars++; - } - else - break; + hexValue = hex (**ptr); + if (hexValue >= 0) + { + *intValue = (*intValue << 4) | hexValue; + numChars++; + } + else + break; - (*ptr)++; - } + (*ptr)++; + } return (numChars); } @@ -844,17 +844,17 @@ handle_exception (int exceptionVector) #endif if (remote_debug) - { - printf ("vector=%d, sr=0x%x, pc=0x%x\n", - exceptionVector, registers[PS], registers[PC]); - } + { + printf ("vector=%d, sr=0x%x, pc=0x%x\n", + exceptionVector, registers[PS], registers[PC]); + } /* reply to host that an exception has occurred */ sigval = computeSignal (exceptionVector); ptr = remcomOutBuffer; - *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ + *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ *ptr++ = hexchars[sigval >> 4]; *ptr++ = hexchars[sigval & 0xf]; @@ -865,7 +865,7 @@ handle_exception (int exceptionVector) *ptr++ = hexchars[EBP]; *ptr++ = ':'; - ptr = mem2hex((char *)®isters[EBP], ptr, 4, 0); /* FP */ + ptr = mem2hex((char *)®isters[EBP], ptr, 4, 0); /* FP */ *ptr++ = ';'; *ptr++ = hexchars[PC]; @@ -880,134 +880,134 @@ handle_exception (int exceptionVector) stepping = 0; while (1 == 1) - { - remcomOutBuffer[0] = 0; - ptr = getpacket (); - - switch (*ptr++) { - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - break; - case 'd': - remote_debug = !(remote_debug); /* toggle debug flag */ - break; - case 'g': /* return the value of the CPU registers */ - mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0); - break; - case 'G': /* set the value of the CPU registers - return OK */ - hex2mem (ptr, (char *) registers, NUMREGBYTES, 0); - strcpy (remcomOutBuffer, "OK"); - break; - case 'P': /* set the value of a single CPU register - return OK */ - { - int regno; + remcomOutBuffer[0] = 0; + ptr = getpacket (); - if (hexToInt (&ptr, ®no) && *ptr++ == '=') - if (regno >= 0 && regno < NUMREGS) + switch (*ptr++) { - hex2mem (ptr, (char *) ®isters[regno], 4, 0); + case '?': + remcomOutBuffer[0] = 'S'; + remcomOutBuffer[1] = hexchars[sigval >> 4]; + remcomOutBuffer[2] = hexchars[sigval % 16]; + remcomOutBuffer[3] = 0; + break; + case 'd': + remote_debug = !(remote_debug); /* toggle debug flag */ + break; + case 'g': /* return the value of the CPU registers */ + mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0); + break; + case 'G': /* set the value of the CPU registers - return OK */ + hex2mem (ptr, (char *) registers, NUMREGBYTES, 0); strcpy (remcomOutBuffer, "OK"); break; - } - - strcpy (remcomOutBuffer, "E01"); - break; - } - - /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - case 'm': - /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ - if (hexToInt (&ptr, &addr)) - if (*(ptr++) == ',') - if (hexToInt (&ptr, &length)) - { - ptr = 0; - mem_err = 0; - mem2hex ((char *) addr, remcomOutBuffer, length, 1); - if (mem_err) - { - strcpy (remcomOutBuffer, "E03"); - debug_error ("memory fault"); - } - } - - if (ptr) - { - strcpy (remcomOutBuffer, "E01"); - } - break; - - /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - case 'M': - /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ - if (hexToInt (&ptr, &addr)) - if (*(ptr++) == ',') - if (hexToInt (&ptr, &length)) - if (*(ptr++) == ':') + case 'P': /* set the value of a single CPU register - return OK */ { - mem_err = 0; - hex2mem (ptr, (char *) addr, length, 1); + int regno; - if (mem_err) - { - strcpy (remcomOutBuffer, "E03"); - debug_error ("memory fault"); - } - else - { - strcpy (remcomOutBuffer, "OK"); - } + if (hexToInt (&ptr, ®no) && *ptr++ == '=') + if (regno >= 0 && regno < NUMREGS) + { + hex2mem (ptr, (char *) ®isters[regno], 4, 0); + strcpy (remcomOutBuffer, "OK"); + break; + } - ptr = 0; + strcpy (remcomOutBuffer, "E01"); + break; } - if (ptr) - { - strcpy (remcomOutBuffer, "E02"); - } - break; - /* cAA..AA Continue at address AA..AA(optional) */ - /* sAA..AA Step one instruction from AA..AA(optional) */ - case 's': - stepping = 1; - case 'c': - /* try to read optional parameter, pc unchanged if no parm */ - if (hexToInt (&ptr, &addr)) - registers[PC] = addr; + /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + case 'm': + /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ + if (hexToInt (&ptr, &addr)) + if (*(ptr++) == ',') + if (hexToInt (&ptr, &length)) + { + ptr = 0; + mem_err = 0; + mem2hex ((char *) addr, remcomOutBuffer, length, 1); + if (mem_err) + { + strcpy (remcomOutBuffer, "E03"); + debug_error ("memory fault"); + } + } - newPC = registers[PC]; + if (ptr) + { + strcpy (remcomOutBuffer, "E01"); + } + break; - /* clear the trace bit */ - registers[PS] &= 0xfffffeff; + /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ + case 'M': + /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ + if (hexToInt (&ptr, &addr)) + if (*(ptr++) == ',') + if (hexToInt (&ptr, &length)) + if (*(ptr++) == ':') + { + mem_err = 0; + hex2mem (ptr, (char *) addr, length, 1); - /* set the trace bit if we're stepping */ - if (stepping) - registers[PS] |= 0x100; + if (mem_err) + { + strcpy (remcomOutBuffer, "E03"); + debug_error ("memory fault"); + } + else + { + strcpy (remcomOutBuffer, "OK"); + } + + ptr = 0; + } + if (ptr) + { + strcpy (remcomOutBuffer, "E02"); + } + break; + + /* cAA..AA Continue at address AA..AA(optional) */ + /* sAA..AA Step one instruction from AA..AA(optional) */ + case 's': + stepping = 1; + case 'c': + /* try to read optional parameter, pc unchanged if no parm */ + if (hexToInt (&ptr, &addr)) + registers[PC] = addr; + + newPC = registers[PC]; + + /* clear the trace bit */ + registers[PS] &= 0xfffffeff; + + /* set the trace bit if we're stepping */ + if (stepping) + registers[PS] |= 0x100; #ifdef WIN32 //MF - return; + return; #else - _returnFromException (); /* this is a jump */ + _returnFromException (); /* this is a jump */ #endif - break; + break; - /* kill the program */ - case 'k': /* do nothing */ + /* kill the program */ + case 'k': /* do nothing */ #if 0 - /* Huh? This doesn't look like "nothing". - m68k-stub.c and sparc-stub.c don't have it. */ - BREAKPOINT (); + /* Huh? This doesn't look like "nothing". + m68k-stub.c and sparc-stub.c don't have it. */ + BREAKPOINT (); #endif - break; - } /* switch */ + break; + } /* switch */ - /* reply to the request */ - putpacket (remcomOutBuffer); - } + /* reply to the request */ + putpacket (remcomOutBuffer); + } } /* this function is used to set up exception handlers for tracing and @@ -1038,7 +1038,7 @@ set_debug_traps (void) initialized = 1; } -/* This function will generate a breakpoint exception. It is used at the +/* This function will generate a breakpoint exception. It is used at the beginning of a program to sync up with a debugger and can be used otherwise as a quick means to stop program execution and "break" into the debugger. */ @@ -1047,7 +1047,7 @@ void breakpoint (void) { if (initialized) - BREAKPOINT (); + BREAKPOINT (); } @@ -1074,21 +1074,21 @@ FILE* ser_port = NULL; int init_gdb_connect() { - //TODO: set up connection using serial communication port + //TODO: set up connection using serial communication port - ser_port = fopen("COM1:", "rwb"); + ser_port = fopen("COM1:", "rwb"); - return 1; + return 1; } int getDebugChar() { - return fgetc(ser_port); + return fgetc(ser_port); } void putDebugChar(int c) { - fputc(c, ser_port); + fputc(c, ser_port); } @@ -1098,67 +1098,67 @@ void putDebugChar(int c) static LPTOP_LEVEL_EXCEPTION_FILTER s_prev_exc_handler = 0; -#define I386_EXCEPTION_CNT 17 +#define I386_EXCEPTION_CNT 17 LONG WINAPI exc_protection_handler(EXCEPTION_POINTERS* exc_info) { - int exc_nr = exc_info->ExceptionRecord->ExceptionCode & 0xFFFF; + int exc_nr = exc_info->ExceptionRecord->ExceptionCode & 0xFFFF; - if (exc_nr < I386_EXCEPTION_CNT) { - //LOG(FmtString(TEXT("exc_protection_handler: Exception %x"), exc_nr)); + if (exc_nr < I386_EXCEPTION_CNT) { + //LOG(FmtString(TEXT("exc_protection_handler: Exception %x"), exc_nr)); - if (exc_nr==11 || exc_nr==13 || exc_nr==14) { - if (mem_fault_routine) - mem_fault_routine(); + if (exc_nr==11 || exc_nr==13 || exc_nr==14) { + if (mem_fault_routine) + mem_fault_routine(); + } + + ++exc_info->ContextRecord->Eip; } - ++exc_info->ContextRecord->Eip; - } - - return EXCEPTION_CONTINUE_EXECUTION; + return EXCEPTION_CONTINUE_EXECUTION; } LONG WINAPI exc_handler(EXCEPTION_POINTERS* exc_info) { - int exc_nr = exc_info->ExceptionRecord->ExceptionCode & 0xFFFF; + int exc_nr = exc_info->ExceptionRecord->ExceptionCode & 0xFFFF; - if (exc_nr < I386_EXCEPTION_CNT) { - //LOG(FmtString("Exception %x", exc_nr)); - //LOG(FmtString("EIP=%08X EFLAGS=%08X", exc_info->ContextRecord->Eip, exc_info->ContextRecord->EFlags)); + if (exc_nr < I386_EXCEPTION_CNT) { + //LOG(FmtString("Exception %x", exc_nr)); + //LOG(FmtString("EIP=%08X EFLAGS=%08X", exc_info->ContextRecord->Eip, exc_info->ContextRecord->EFlags)); - // step over initial breakpoint - if (s_initial_breakpoint) { - s_initial_breakpoint = 0; - ++exc_info->ContextRecord->Eip; + // step over initial breakpoint + if (s_initial_breakpoint) { + s_initial_breakpoint = 0; + ++exc_info->ContextRecord->Eip; + } + + SetUnhandledExceptionFilter(exc_protection_handler); + + win32_exception_handler(exc_info); + //LOG(FmtString("EIP=%08X EFLAGS=%08X", exc_info->ContextRecord->Eip, exc_info->ContextRecord->EFlags)); + + SetUnhandledExceptionFilter(exc_handler); + + return EXCEPTION_CONTINUE_EXECUTION; } - SetUnhandledExceptionFilter(exc_protection_handler); - - win32_exception_handler(exc_info); - //LOG(FmtString("EIP=%08X EFLAGS=%08X", exc_info->ContextRecord->Eip, exc_info->ContextRecord->EFlags)); - - SetUnhandledExceptionFilter(exc_handler); - - return EXCEPTION_CONTINUE_EXECUTION; - } - - return EXCEPTION_CONTINUE_SEARCH; + return EXCEPTION_CONTINUE_SEARCH; } /* not needed because we use win32_exception_handler() instead of catchExceptionX() void exceptionHandler(int exc_nr, void* exc_addr) { - if (exc_nr>=0 && exc_nr=0 && exc_nr_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + if (!(p->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && // not a directory? + !p->_down) // not a file with NTFS sub-streams? return FALSE; idx = ListBox_FindItemData(_left_hwnd, 0, dir); @@ -407,7 +408,9 @@ void FileChildWindow::activate_entry(Pane* pane, HWND hwnd) if (!entry) return; - if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if ((entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || // a directory? + entry->_down) // a file with NTFS sub-streams? + { int scanned_old = entry->_scanned; if (!scanned_old) diff --git a/reactos/subsys/system/explorer/shell/pane.cpp b/reactos/subsys/system/explorer/shell/pane.cpp index 4e58f13d715..0a18e95b9d2 100644 --- a/reactos/subsys/system/explorer/shell/pane.cpp +++ b/reactos/subsys/system/explorer/shell/pane.cpp @@ -408,7 +408,8 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol) if (up->_next #ifndef _LEFT_FILES - && (up->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + && ((up->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) // a directory? + || up->_next->_down) // a file with NTFS sub-streams? #endif ) { MoveToEx(dis->hDC, x, dis->rcItem.top, 0); @@ -424,7 +425,8 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol) if (entry->_next #ifndef _LEFT_FILES - && (entry->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + && ((entry->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) // a directory? + || entry->_next->_down) // a file with NTFS sub-streams? #endif ) LineTo(dis->hDC, x, dis->rcItem.bottom); @@ -661,7 +663,9 @@ void Pane::insert_entries(Entry* dir, int idx) for(; entry; entry=entry->_next) { #ifndef _LEFT_FILES - if (_treePane && !(entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) + if (_treePane && + !(entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && // not a directory? + !entry->_down) // not a file with NTFS sub-streams? continue; #endif diff --git a/reactos/subsys/system/explorer/shell/winfs.cpp b/reactos/subsys/system/explorer/shell/winfs.cpp index e0c4a6671d2..e1089fb1525 100644 --- a/reactos/subsys/system/explorer/shell/winfs.cpp +++ b/reactos/subsys/system/explorer/shell/winfs.cpp @@ -33,6 +33,86 @@ #include "winfs.h" +int ScanNTFSStreams(Entry* entry, HANDLE hFile) +{ + PVOID ctx = 0; + DWORD read, seek_high; + Entry** pnext = &entry->_down; + int cnt = 0; + + for(;;) { + struct NTFS_StreamHdr : public WIN32_STREAM_ID { + WCHAR name_padding[_MAX_FNAME]; // room for reading stream name + } hdr; + + if (!BackupRead(hFile, (LPBYTE)&hdr, (LPBYTE)&hdr.cStreamName-(LPBYTE)&hdr, &read, FALSE, FALSE, &ctx) || (long)read!=(LPBYTE)&hdr.cStreamName-(LPBYTE)&hdr) + break; + + if (hdr.dwStreamId == BACKUP_ALTERNATE_DATA) { + if (hdr.dwStreamNameSize && + BackupRead(hFile, (LPBYTE)hdr.cStreamName, hdr.dwStreamNameSize, &read, FALSE, FALSE, &ctx) && + read==hdr.dwStreamNameSize) + { + ++cnt; + + int l = hdr.dwStreamNameSize / sizeof(WCHAR); + LPCWSTR p = hdr.cStreamName; + LPCWSTR e = hdr.cStreamName + l; + + if (l>0 && *p==':') { + ++p, --l; + + e = p; + + while(l>0 && *e!=':') + ++e, --l; + + l = e - p; + } + + Entry* stream_entry = new WinEntry(entry); + + memcpy(&stream_entry->_data, &entry->_data, sizeof(WIN32_FIND_DATA)); + + lstrcpy(stream_entry->_data.cFileName, String(p, l)); + + stream_entry->_down = NULL; + stream_entry->_expanded = false; + stream_entry->_scanned = false; + stream_entry->_level = entry->_level + 1; + stream_entry->_bhfi_valid = false; + + *pnext = stream_entry; + pnext = &stream_entry->_next; + } + } else if (hdr.dwStreamId == BACKUP_SPARSE_BLOCK) { + DWORD sparse_buffer[2]; + + if (!BackupRead(hFile, (LPBYTE)&sparse_buffer, 8, &read, FALSE, FALSE, &ctx)) { + BackupRead(hFile, 0, 0, &read, TRUE, FALSE, &ctx); + THROW_EXCEPTION(GetLastError()); + } + } + + // jump to the next stream header + if (!BackupSeek(hFile, ~0, ~0, &read, &seek_high, &ctx)) { + DWORD error = GetLastError(); + + if (error != ERROR_SEEK) { + BackupRead(hFile, 0, 0, &read, TRUE, FALSE, &ctx); + THROW_EXCEPTION(error); + //break; + } + } + } + + if (!BackupRead(hFile, 0, 0, &read, TRUE, FALSE, &ctx)) + THROW_EXCEPTION(GetLastError()); + + return cnt; +} + + void WinDirectory::read_directory() { Entry* first_entry = NULL; @@ -80,6 +160,9 @@ void WinDirectory::read_directory() if (GetFileInformationByHandle(hFile, &entry->_bhfi)) entry->_bhfi_valid = true; + if (ScanNTFSStreams(entry, hFile)) + entry->_scanned = true; // There exist named NTFS sub-streams in this file. + CloseHandle(hFile); } @@ -158,7 +241,10 @@ void WinEntry::get_path(PTSTR path) const memcpy(path+1, name, l*sizeof(TCHAR)); len += l+1; - path[0] = TEXT('\\'); + if (entry->_up && !(entry->_up->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) // a NTFS stream? + path[0] = TEXT(':'); + else + path[0] = TEXT('\\'); } entry = entry->_up; diff --git a/reactos/subsys/system/explorer/utility/shellclasses.h b/reactos/subsys/system/explorer/utility/shellclasses.h index 174a455dc2b..f5b9bbfe373 100644 --- a/reactos/subsys/system/explorer/utility/shellclasses.h +++ b/reactos/subsys/system/explorer/utility/shellclasses.h @@ -144,7 +144,8 @@ struct COMException : public COMExceptionBase int _line; }; -#define CHECKERROR(hr) ((void)(FAILED(hr)? throw COMException(hr, __FILE__, __LINE__): 0)) +#define THROW_EXCEPTION(e) throw COMException(e, __FILE__, __LINE__) +#define CHECKERROR(hr) ((void)(FAILED(hr)? THROW_EXCEPTION(hr): 0)) #ifdef _NO_COMUTIL diff --git a/reactos/subsys/system/explorer/utility/utility.h b/reactos/subsys/system/explorer/utility/utility.h index 4edd3587eba..49f5426bf71 100644 --- a/reactos/subsys/system/explorer/utility/utility.h +++ b/reactos/subsys/system/explorer/utility/utility.h @@ -581,19 +581,24 @@ struct String String() {} String(LPCTSTR s) : super(s) {} + String(LPCTSTR s, int l) : super(s, l) {} String(const super& other) : super(other) {} String(const String& other) : super(other) {} #ifdef UNICODE String(LPCSTR s) {assign(s);} + String(LPCSTR s, int l) {assign(s, l);} String(const string& other) {assign(other.c_str());} String& operator=(LPCSTR s) {assign(s); return *this;} void assign(LPCSTR s) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, -1, b, BUFFER_LEN));} + void assign(LPCSTR s, int l) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, l, b, BUFFER_LEN));} #else String(LPCWSTR s) {assign(s);} + String(LPCWSTR s, int l) {assign(s, l);} String(const wstring& other) {assign(other.c_str());} String& operator=(LPCWSTR s) {assign(s); return *this;} void assign(LPCWSTR s) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, -1, b, BUFFER_LEN, 0, 0));} + void assign(LPCWSTR s, int l) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, l, b, BUFFER_LEN, 0, 0));} #endif String& operator=(LPCTSTR s) {super::assign(s); return *this;}