ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

lzexpand.c
Go to the documentation of this file.
00001 /* $Id: lzexpand.c 52854 2011-07-24 23:42:09Z ion $
00002  * 
00003  * LZ Decompression functions
00004  *
00005  * Copyright 1996 Marcus Meissner
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  *
00021  * NOTES
00022  *
00023  * The LZ (Lempel Ziv) decompression was used in win16 installation programs.
00024  * It is a simple tabledriven decompression engine, the algorithm is not
00025  * documented as far as I know. WINE does not contain a compressor for
00026  * this format.
00027  *
00028  * The implementation is complete and there have been no reports of failures
00029  * for some time.
00030  *
00031  * TODO:
00032  *
00033  *   o Check whether the return values are correct
00034  *
00035  */
00036 //#include <k32.h>
00037 #define HFILE_ERROR ((HFILE)-1)
00038 
00039 //#include "config.h"
00040 #include <string.h>
00041 #include <ctype.h>
00042 #include <sys/types.h>
00043 #include <stdarg.h>
00044 #include <stdio.h>
00045 #ifdef HAVE_UNISTD_H
00046 #include <unistd.h>
00047 #endif
00048 
00049 #include "windef.h"
00050 #include "winbase.h"
00051 #include "lzexpand.h"
00052 
00053 #include "wine/unicode.h"
00054 #include "wine/debug.h"
00055 #include "winternl.h"
00056 #define HeapAlloc RtlAllocateHeap
00057 #define HeapReAlloc RtlReAllocateHeap
00058 #define HeapFree RtlFreeHeap
00059 #define _lread(a, b, c)  (long)(_hread(a, b, (long)c))
00060 #define _lwrite(a, b, c) (long)(_hwrite(a, b, (long)c))
00061 WINE_DEFAULT_DEBUG_CHANNEL(file);
00062    
00063 /* The readahead length of the decompressor. Reading single bytes
00064  * using _lread() would be SLOW.
00065  */
00066 #define GETLEN  2048
00067 
00068 #define LZ_MAGIC_LEN    8
00069 #define LZ_HEADER_LEN   14
00070 
00071 /* Format of first 14 byte of LZ compressed file */
00072 struct lzfileheader {
00073     BYTE    magic[LZ_MAGIC_LEN];
00074     BYTE    compressiontype;
00075     CHAR    lastchar;
00076     DWORD   reallength;
00077 };
00078 static const BYTE LZMagic[LZ_MAGIC_LEN]={'S','Z','D','D',0x88,0xf0,0x27,0x33};
00079 
00080 #define LZ_TABLE_SIZE    0x1000
00081 
00082 struct lzstate {
00083     HFILE   realfd;     /* the real filedescriptor */
00084     CHAR    lastchar;   /* the last char of the filename */
00085 
00086     DWORD   reallength; /* the decompressed length of the file */
00087     DWORD   realcurrent;    /* the position the decompressor currently is */
00088     DWORD   realwanted; /* the position the user wants to read from */
00089 
00090     BYTE    table[LZ_TABLE_SIZE];   /* the rotating LZ table */
00091     UINT    curtabent;  /* CURrent TABle ENTry */
00092 
00093     BYTE    stringlen;  /* length and position of current string */
00094     DWORD   stringpos;  /* from stringtable */
00095 
00096 
00097     WORD    bytetype;   /* bitmask within blocks */
00098 
00099     BYTE    *get;       /* GETLEN bytes */
00100     DWORD   getcur;     /* current read */
00101     DWORD   getlen;     /* length last got */
00102 };
00103 
00104 #define MAX_LZSTATES 16
00105 static struct lzstate *lzstates[MAX_LZSTATES];
00106 
00107 #define LZ_MIN_HANDLE  0x400
00108 #define IS_LZ_HANDLE(h) (((h) >= LZ_MIN_HANDLE) && ((h) < LZ_MIN_HANDLE+MAX_LZSTATES))
00109 #define GET_LZ_STATE(h) (IS_LZ_HANDLE(h) ? lzstates[(h)-LZ_MIN_HANDLE] : NULL)
00110 
00111 /* reads one compressed byte, including buffering */
00112 #define GET(lzs,b)  _lzget(lzs,&b)
00113 #define GET_FLUSH(lzs)  lzs->getcur=lzs->getlen;
00114 
00115 static int
00116 _lzget(struct lzstate *lzs,BYTE *b) {
00117     if (lzs->getcur<lzs->getlen) {
00118         *b      = lzs->get[lzs->getcur++];
00119         return      1;
00120     } else {
00121         int ret = _lread(lzs->realfd,lzs->get,GETLEN);
00122         if (ret==HFILE_ERROR)
00123             return HFILE_ERROR;
00124         if (ret==0)
00125             return 0;
00126         lzs->getlen = ret;
00127         lzs->getcur = 1;
00128         *b      = *(lzs->get);
00129         return 1;
00130     }
00131 }
00132 /* internal function, reads lzheader
00133  * returns BADINHANDLE for non filedescriptors
00134  * return 0 for file not compressed using LZ
00135  * return UNKNOWNALG for unknown algorithm
00136  * returns lzfileheader in *head
00137  */
00138 static INT read_header(HFILE fd,struct lzfileheader *head)
00139 {
00140     BYTE    buf[LZ_HEADER_LEN];
00141 
00142     if (_llseek(fd,0,SEEK_SET)==-1)
00143         return LZERROR_BADINHANDLE;
00144 
00145     /* We can't directly read the lzfileheader struct due to
00146      * structure element alignment
00147      */
00148     if (_lread(fd,buf,LZ_HEADER_LEN)<LZ_HEADER_LEN)
00149         return 0;
00150     memcpy(head->magic,buf,LZ_MAGIC_LEN);
00151     memcpy(&(head->compressiontype),buf+LZ_MAGIC_LEN,1);
00152     memcpy(&(head->lastchar),buf+LZ_MAGIC_LEN+1,1);
00153 
00154     /* FIXME: consider endianess on non-intel architectures */
00155     memcpy(&(head->reallength),buf+LZ_MAGIC_LEN+2,4);
00156 
00157     if (memcmp(head->magic,LZMagic,LZ_MAGIC_LEN))
00158         return 0;
00159     if (head->compressiontype!='A')
00160         return LZERROR_UNKNOWNALG;
00161     return 1;
00162 }
00163 
00164 
00165 /***********************************************************************
00166  *           LZStart   (KERNEL32.@)
00167  */
00168 INT WINAPI LZStart(void)
00169 {
00170     TRACE("(void)\n");
00171     return 1;
00172 }
00173 
00174 
00175 /***********************************************************************
00176  *           LZInit   (KERNEL32.@)
00177  *
00178  * initializes internal decompression buffers, returns lzfiledescriptor.
00179  * (return value the same as hfSrc, if hfSrc is not compressed)
00180  * on failure, returns error code <0
00181  * lzfiledescriptors range from 0x400 to 0x410 (only 16 open files per process)
00182  *
00183  * since _llseek uses the same types as libc.lseek, we just use the macros of
00184  *  libc
00185  */
00186 HFILE WINAPI LZInit( HFILE hfSrc )
00187 {
00188 
00189     struct  lzfileheader    head;
00190     struct  lzstate     *lzs;
00191     int i, ret;
00192 
00193     TRACE("(%d)\n",hfSrc);
00194     ret=read_header(hfSrc,&head);
00195     if (ret<=0) {
00196         _llseek(hfSrc,0,SEEK_SET);
00197         return ret?ret:hfSrc;
00198     }
00199         for (i = 0; i < MAX_LZSTATES; i++) if (!lzstates[i]) break;
00200         if (i == MAX_LZSTATES) return LZERROR_GLOBALLOC;
00201     lzstates[i] = lzs = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*lzs) );
00202     if(lzs == NULL) return LZERROR_GLOBALLOC;
00203 
00204     lzs->realfd = hfSrc;
00205     lzs->lastchar   = head.lastchar;
00206     lzs->reallength = head.reallength;
00207 
00208     lzs->get    = HeapAlloc( GetProcessHeap(), 0, GETLEN );
00209     lzs->getlen = 0;
00210     lzs->getcur = 0;
00211 
00212     if(lzs->get == NULL) {
00213         HeapFree(GetProcessHeap(), 0, lzs);
00214         lzstates[i] = NULL;
00215         return LZERROR_GLOBALLOC;
00216     }
00217 
00218     /* Yes, preinitialize with spaces */
00219     memset(lzs->table,' ',LZ_TABLE_SIZE);
00220     /* Yes, start 16 byte from the END of the table */
00221     lzs->curtabent  = 0xff0;
00222     return LZ_MIN_HANDLE + i;
00223 }
00224 
00225 
00226 /***********************************************************************
00227  *           LZDone   (KERNEL32.@)
00228  */
00229 void WINAPI LZDone(void)
00230 {
00231     TRACE("(void)\n");
00232 }
00233 
00234 
00235 /***********************************************************************
00236  *           GetExpandedNameA   (KERNEL32.@)
00237  *
00238  * gets the full filename of the compressed file 'in' by opening it
00239  * and reading the header
00240  *
00241  * "file." is being translated to "file"
00242  * "file.bl_" (with lastchar 'a') is being translated to "file.bla"
00243  * "FILE.BL_" (with lastchar 'a') is being translated to "FILE.BLA"
00244  */
00245 
00246 INT WINAPI GetExpandedNameA( LPSTR in, LPSTR out )
00247 {
00248     struct lzfileheader head;
00249     HFILE       fd;
00250     OFSTRUCT    ofs;
00251     INT     fnislowercased,ret,len;
00252     LPSTR       s,t;
00253 
00254     TRACE("(%s)\n",in);
00255     fd=OpenFile(in,&ofs,OF_READ);
00256     if (fd==HFILE_ERROR)
00257         return (INT)(INT16)LZERROR_BADINHANDLE;
00258     strcpy(out,in);
00259     ret=read_header(fd,&head);
00260     if (ret<=0) {
00261         /* not a LZ compressed file, so the expanded name is the same
00262          * as the input name */
00263         _lclose(fd);
00264         return 1;
00265     }
00266 
00267 
00268     /* look for directory prefix and skip it. */
00269     s=out;
00270     while (NULL!=(t=strpbrk(s,"/\\:")))
00271         s=t+1;
00272 
00273     /* now mangle the basename */
00274     if (!*s) {
00275         /* FIXME: hmm. shouldn't happen? */
00276         WARN("Specified a directory or what? (%s)\n",in);
00277         _lclose(fd);
00278         return 1;
00279     }
00280     /* see if we should use lowercase or uppercase on the last char */
00281     fnislowercased=1;
00282     t=s+strlen(s)-1;
00283     while (t>=out) {
00284         if (!isalpha(*t)) {
00285             t--;
00286             continue;
00287         }
00288         fnislowercased=islower(*t);
00289         break;
00290     }
00291     if (isalpha(head.lastchar)) {
00292         if (fnislowercased)
00293             head.lastchar=tolower(head.lastchar);
00294         else
00295             head.lastchar=toupper(head.lastchar);
00296     }
00297 
00298     /* now look where to replace the last character */
00299     if (NULL!=(t=strchr(s,'.'))) {
00300         if (t[1]=='\0') {
00301             t[0]='\0';
00302         } else {
00303             len=strlen(t)-1;
00304             if (t[len]=='_')
00305                 t[len]=head.lastchar;
00306         }
00307     } /* else no modification necessary */
00308     _lclose(fd);
00309     return 1;
00310 }
00311 
00312 
00313 /***********************************************************************
00314  *           GetExpandedNameW   (KERNEL32.@)
00315  */
00316 INT WINAPI GetExpandedNameW( LPWSTR in, LPWSTR out )
00317 {
00318     INT ret;
00319     DWORD len = WideCharToMultiByte( CP_ACP, 0, in, -1, NULL, 0, NULL, NULL );
00320     char *xin = HeapAlloc( GetProcessHeap(), 0, len );
00321     char *xout = HeapAlloc( GetProcessHeap(), 0, len+3 );
00322     WideCharToMultiByte( CP_ACP, 0, in, -1, xin, len, NULL, NULL );
00323     if ((ret = GetExpandedNameA( xin, xout )) > 0)
00324         MultiByteToWideChar( CP_ACP, 0, xout, -1, out, strlenW(in)+4 );
00325     HeapFree( GetProcessHeap(), 0, xin );
00326     HeapFree( GetProcessHeap(), 0, xout );
00327     return ret;
00328 }
00329 
00330 
00331 /***********************************************************************
00332  *           LZRead   (KERNEL32.@)
00333  */
00334 INT WINAPI LZRead( HFILE fd, LPSTR vbuf, INT toread )
00335 {
00336     int howmuch;
00337     BYTE    b,*buf;
00338     struct  lzstate *lzs;
00339 
00340     buf=(LPBYTE)vbuf;
00341     TRACE("(%d,%p,%d)\n",fd,buf,toread);
00342     howmuch=toread;
00343     if (!(lzs = GET_LZ_STATE(fd))) return _lread(fd,buf,toread);
00344 
00345 /* The decompressor itself is in a define, cause we need it twice
00346  * in this function. (the decompressed byte will be in b)
00347  */
00348 #define DECOMPRESS_ONE_BYTE                         \
00349         if (lzs->stringlen) {                   \
00350             b       = lzs->table[lzs->stringpos];   \
00351             lzs->stringpos  = (lzs->stringpos+1)&0xFFF; \
00352             lzs->stringlen--;               \
00353         } else {                        \
00354             if (!(lzs->bytetype&0x100)) {           \
00355                 if (1!=GET(lzs,b))          \
00356                     return toread-howmuch;      \
00357                 lzs->bytetype = b|0xFF00;       \
00358             }                       \
00359             if (lzs->bytetype & 1) {            \
00360                 if (1!=GET(lzs,b))          \
00361                     return toread-howmuch;      \
00362             } else {                    \
00363                 BYTE    b1,b2;              \
00364                                     \
00365                 if (1!=GET(lzs,b1))         \
00366                     return toread-howmuch;      \
00367                 if (1!=GET(lzs,b2))         \
00368                     return toread-howmuch;      \
00369                 /* Format:              \
00370                  * b1 b2                \
00371                  * AB CD                \
00372                  * where CAB is the stringoffset in the table\
00373                  * and D+3 is the len of the string \
00374                  */                 \
00375                 lzs->stringpos  = b1|((b2&0xf0)<<4);    \
00376                 lzs->stringlen  = (b2&0xf)+2;       \
00377                 /* 3, but we use a  byte already below ... */\
00378                 b       = lzs->table[lzs->stringpos];\
00379                 lzs->stringpos  = (lzs->stringpos+1)&0xFFF;\
00380             }                       \
00381             lzs->bytetype>>=1;              \
00382         }                           \
00383         /* store b in table */                  \
00384         lzs->table[lzs->curtabent++]= b;            \
00385         lzs->curtabent  &= 0xFFF;               \
00386         lzs->realcurrent++;
00387 
00388     /* if someone has seeked, we have to bring the decompressor
00389      * to that position
00390      */
00391     if (lzs->realcurrent!=lzs->realwanted) {
00392         /* if the wanted position is before the current position
00393          * I see no easy way to unroll ... We have to restart at
00394          * the beginning. *sigh*
00395          */
00396         if (lzs->realcurrent>lzs->realwanted) {
00397             /* flush decompressor state */
00398             _llseek(lzs->realfd,LZ_HEADER_LEN,SEEK_SET);
00399             GET_FLUSH(lzs);
00400             lzs->realcurrent= 0;
00401             lzs->bytetype   = 0;
00402             lzs->stringlen  = 0;
00403             memset(lzs->table,' ',LZ_TABLE_SIZE);
00404             lzs->curtabent  = 0xFF0;
00405         }
00406         while (lzs->realcurrent<lzs->realwanted) {
00407             DECOMPRESS_ONE_BYTE;
00408         }
00409     }
00410 
00411     while (howmuch) {
00412         DECOMPRESS_ONE_BYTE;
00413         lzs->realwanted++;
00414         *buf++      = b;
00415         howmuch--;
00416     }
00417     return  toread;
00418 #undef DECOMPRESS_ONE_BYTE
00419 }
00420 
00421 
00422 /***********************************************************************
00423  *           LZSeek   (KERNEL32.@)
00424  */
00425 LONG WINAPI LZSeek( HFILE fd, LONG off, INT type )
00426 {
00427     struct  lzstate *lzs;
00428     LONG    newwanted;
00429 
00430     TRACE("(%d,%d,%d)\n",fd,off,type);
00431     /* not compressed? just use normal _llseek() */
00432         if (!(lzs = GET_LZ_STATE(fd))) return _llseek(fd,off,type);
00433     newwanted = lzs->realwanted;
00434     switch (type) {
00435     case 1: /* SEEK_CUR */
00436         newwanted      += off;
00437         break;
00438     case 2: /* SEEK_END */
00439         newwanted   = lzs->reallength-off;
00440         break;
00441     default:/* SEEK_SET */
00442         newwanted   = off;
00443         break;
00444     }
00445     if (newwanted>lzs->reallength)
00446         return LZERROR_BADVALUE;
00447     if (newwanted<0)
00448         return LZERROR_BADVALUE;
00449     lzs->realwanted = newwanted;
00450     return newwanted;
00451 }
00452 
00453 
00454 /***********************************************************************
00455  *           LZCopy   (KERNEL32.@)
00456  *
00457  * Copies everything from src to dest
00458  * if src is a LZ compressed file, it will be uncompressed.
00459  * will return the number of bytes written to dest or errors.
00460  */
00461 LONG WINAPI LZCopy( HFILE src, HFILE dest )
00462 {
00463     int usedlzinit = 0, ret, wret;
00464     LONG    len;
00465     HFILE   oldsrc = src, srcfd;
00466     FILETIME filetime;
00467     struct  lzstate *lzs;
00468 #define BUFLEN  1000
00469     CHAR    buf[BUFLEN];
00470     /* we need that weird typedef, for i can't seem to get function pointer
00471      * casts right. (Or they probably just do not like WINAPI in general)
00472      */
00473     typedef UINT    (WINAPI *_readfun)(HFILE,LPVOID,UINT);
00474 
00475     _readfun    xread;
00476 
00477     TRACE("(%d,%d)\n",src,dest);
00478     if (!IS_LZ_HANDLE(src)) {
00479         src = LZInit(src);
00480                 if ((INT)src <= 0) return 0;
00481         if (src != oldsrc) usedlzinit=1;
00482     }
00483 
00484     /* not compressed? just copy */
00485         if (!IS_LZ_HANDLE(src))
00486         xread=(_readfun)_hread; // ROSHACK
00487     else
00488         xread=(_readfun)LZRead;
00489     len=0;
00490     while (1) {
00491         ret=xread(src,buf,BUFLEN);
00492         if (ret<=0) {
00493             if (ret==0)
00494                 break;
00495             if (ret==-1)
00496                 return LZERROR_READ;
00497             return ret;
00498         }
00499         len    += ret;
00500         wret    = _lwrite(dest,buf,ret);
00501         if (wret!=ret)
00502             return LZERROR_WRITE;
00503     }
00504 
00505     /* Maintain the timestamp of source file to destination file */
00506     srcfd = (!(lzs = GET_LZ_STATE(src))) ? src : lzs->realfd;
00507     GetFileTime( LongToHandle(srcfd), NULL, NULL, &filetime );
00508     SetFileTime( LongToHandle(dest), NULL, NULL, &filetime );
00509 
00510     /* close handle */
00511     if (usedlzinit)
00512         LZClose(src);
00513     return len;
00514 #undef BUFLEN
00515 }
00516 
00517 /* reverses GetExpandedPathname */
00518 static LPSTR LZEXPAND_MangleName( LPCSTR fn )
00519 {
00520     char *p;
00521     char *mfn = HeapAlloc( GetProcessHeap(), 0, strlen(fn) + 3 ); /* "._" and \0 */
00522     if(mfn == NULL) return NULL;
00523     strcpy( mfn, fn );
00524     if (!(p = strrchr( mfn, '\\' ))) p = mfn;
00525     if ((p = strchr( p, '.' )))
00526     {
00527         p++;
00528         if (strlen(p) < 3) strcat( p, "_" );  /* append '_' */
00529         else p[strlen(p)-1] = '_';  /* replace last character */
00530     }
00531     else strcat( mfn, "._" );   /* append "._" */
00532     return mfn;
00533 }
00534 
00535 
00536 /***********************************************************************
00537  *           LZOpenFileA   (KERNEL32.@)
00538  *
00539  * Opens a file. If not compressed, open it as a normal file.
00540  */
00541 HFILE WINAPI LZOpenFileA( LPSTR fn, LPOFSTRUCT ofs, WORD mode )
00542 {
00543     HFILE   fd,cfd;
00544 
00545     TRACE("(%s,%p,%d)\n",fn,ofs,mode);
00546     /* 0x70 represents all OF_SHARE_* flags, ignore them for the check */
00547     fd=OpenFile(fn,ofs,mode);
00548     if (fd==HFILE_ERROR)
00549         {
00550             LPSTR mfn = LZEXPAND_MangleName(fn);
00551             fd = OpenFile(mfn,ofs,mode);
00552             HeapFree( GetProcessHeap(), 0, mfn );
00553     }
00554     if ((mode&~0x70)!=OF_READ)
00555         return fd;
00556     if (fd==HFILE_ERROR)
00557         return HFILE_ERROR;
00558     cfd=LZInit(fd);
00559     if ((INT)cfd <= 0) return fd;
00560     return cfd;
00561 }
00562 
00563 
00564 /***********************************************************************
00565  *           LZOpenFileW   (KERNEL32.@)
00566  */
00567 HFILE WINAPI LZOpenFileW( LPWSTR fn, LPOFSTRUCT ofs, WORD mode )
00568 {
00569     HFILE ret;
00570     DWORD len = WideCharToMultiByte( CP_ACP, 0, fn, -1, NULL, 0, NULL, NULL );
00571     LPSTR xfn = HeapAlloc( GetProcessHeap(), 0, len );
00572     WideCharToMultiByte( CP_ACP, 0, fn, -1, xfn, len, NULL, NULL );
00573     ret = LZOpenFileA(xfn,ofs,mode);
00574     HeapFree( GetProcessHeap(), 0, xfn );
00575     return ret;
00576 }
00577 
00578 
00579 /***********************************************************************
00580  *           LZClose   (KERNEL32.@)
00581  */
00582 void WINAPI LZClose( HFILE fd )
00583 {
00584     struct lzstate *lzs;
00585 
00586     TRACE("(%d)\n",fd);
00587         if (!(lzs = GET_LZ_STATE(fd))) _lclose(fd);
00588         else
00589         {
00590             HeapFree( GetProcessHeap(), 0, lzs->get );
00591             CloseHandle( LongToHandle(lzs->realfd) );
00592             lzstates[fd - LZ_MIN_HANDLE] = NULL;
00593             HeapFree( GetProcessHeap(), 0, lzs );
00594         }
00595 }
00596 
00597 /*
00598  * @implemented
00599  */
00600 VOID
00601 WINAPI
00602 LZCloseFile(IN HFILE FileHandle)
00603 {
00604     /* One function uses _lclose, the other CloseHandle -- same thing */
00605     LZClose(FileHandle);
00606 }
00607 
00608 /*
00609  * @unimplemented
00610  */
00611 ULONG
00612 WINAPI
00613 LZCreateFileW(IN LPCWSTR FileName,
00614               IN DWORD dwDesiredAccess,
00615               IN DWORD dwShareMode,
00616               IN DWORD dwCreationDisposition,
00617               IN LPWSTR lpString1)
00618 {
00619     WARN(" LZCreateFileW Not implemented!\n");
00620     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00621     return ERROR_CALL_NOT_IMPLEMENTED;
00622 }
00623 

Generated on Sun May 27 2012 04:24:34 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.