- implement FDI{Create,Destroy,IsCabinet}
- fix a typo - duplicate a bug - some blathering about code duplication - change fdi.c indentation to be consistent with cabextract.c
This commit is contained in:
parent
eee3a24dc9
commit
6f27b3bc06
|
@ -21,6 +21,8 @@
|
|||
#define __WINE_CABINET_H
|
||||
|
||||
#include "winnt.h"
|
||||
#include "fdi.h"
|
||||
#include "fci.h"
|
||||
|
||||
#define CAB_SPLITMAX (10)
|
||||
|
||||
|
@ -285,6 +287,50 @@ typedef struct cds_forward {
|
|||
} methods;
|
||||
} cab_decomp_state;
|
||||
|
||||
/* _Int as in "Internal" fyi */
|
||||
|
||||
typedef struct {
|
||||
unsigned int FCI_Intmagic;
|
||||
} FCI_Int, *PFCI_Int;
|
||||
|
||||
typedef struct {
|
||||
unsigned int FDI_Intmagic;
|
||||
PFNALLOC pfnalloc;
|
||||
PFNFREE pfnfree;
|
||||
PFNOPEN pfnopen;
|
||||
PFNREAD pfnread;
|
||||
PFNWRITE pfnwrite;
|
||||
PFNCLOSE pfnclose;
|
||||
PFNSEEK pfnseek;
|
||||
PERF perf;
|
||||
} FDI_Int, *PFDI_Int;
|
||||
|
||||
/* cast an HFCI into a PFCI_Int */
|
||||
#define PFCI_INT(hfci) ((PFDI_Int)(hfci))
|
||||
|
||||
/* cast an HFDI into a PFDI_Int */
|
||||
#define PFDI_INT(hfdi) ((PFDI_Int)(hfdi))
|
||||
|
||||
/* quickie pfdi method invokers */
|
||||
#define PFDI_ALLOC(hfdi, size) ((*PFDI_INT(hfdi)->pfnalloc) (size))
|
||||
#define PFDI_FREE(hfdi, ptr) ((*PFDI_INT(hfdi)->pfnfree) (ptr))
|
||||
#define PFDI_OPEN(hfdi, file, flag, mode) ((*PFDI_INT(hfdi)->pfnopen) (file, flag, mode))
|
||||
#define PFDI_READ(hfdi, hf, pv, cb) ((*PFDI_INT(hfdi)->pfnread) (hf, pv, cb))
|
||||
#define PFDI_WRITE(hfdi, hf, pv, cb) ((*PFDI_INT(hfdi)->pfnwrite) (hf, pv, cb))
|
||||
#define PFDI_CLOSE(hfdi, hf) ((*PFDI_INT(hfdi)->pfnclose) (hf))
|
||||
#define PFDI_SEEK(hfdi, hf, dist, type) ((*PFDI_INT(hfdi)->pfnseek) (hf, dist, type))
|
||||
|
||||
#define FCI_INT_MAGIC 0xfcfcfc05
|
||||
#define FDI_INT_MAGIC 0xfdfdfd05
|
||||
|
||||
#define REALLY_IS_FCI(hfci) ( \
|
||||
(((void *) hfci) != NULL) && \
|
||||
(PFCI_INT(hfci)->FCI_Intmagic == FCI_INT_MAGIC) )
|
||||
|
||||
#define REALLY_IS_FDI(hfdi) ( \
|
||||
(((void *) hfdi) != NULL) && \
|
||||
(PFDI_INT(hfdi)->FDI_Intmagic == FDI_INT_MAGIC) )
|
||||
|
||||
/* from cabextract.c */
|
||||
BOOL process_cabinet(LPCSTR cabname, LPCSTR dir, BOOL fix, BOOL lower);
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/*
|
||||
* File Decompression Interface
|
||||
*
|
||||
* Copyright 2000-2002 Stuart Caie
|
||||
* Copyright 2002 Patrik Stridvall
|
||||
* Copyright 2003 Greg Turner
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -16,14 +18,25 @@
|
|||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* This is (or will be) a largely redundant reimplementation of the stuff in
|
||||
* cabextract.c... it would theoretically be preferable to have only one, shared
|
||||
* implementation, however there are semantic differences which may discourage efforts
|
||||
* to unify the two. It should be possible, if awkward, to go back and reimplement
|
||||
* cabextract.c using FDI (once the FDI implementation is complete, of course).
|
||||
* -gmt
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "fdi.h"
|
||||
#include "cabinet.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -43,19 +56,291 @@ HFDI __cdecl FDICreate(
|
|||
int cpuType,
|
||||
PERF perf)
|
||||
{
|
||||
FIXME("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, \
|
||||
pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p): stub\n",
|
||||
HFDI rv;
|
||||
|
||||
TRACE("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, \
|
||||
pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p)\n",
|
||||
pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek,
|
||||
cpuType, perf);
|
||||
|
||||
/* PONDERME: Certainly, we cannot tolerate a missing pfnalloc, as we call it just below.
|
||||
pfnfree is tested as well, for symmetry. As for the rest, should we test these
|
||||
too? In a vacuum, I would say yes... but does Windows care? If not, then, I guess,
|
||||
neither can we.... */
|
||||
if ((!pfnalloc) || (!pfnfree)) {
|
||||
perf->erfOper = FDIERROR_NONE;
|
||||
perf->erfType = 0;
|
||||
perf->erfType = ERROR_BAD_ARGUMENTS;
|
||||
perf->fError = TRUE;
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
SetLastError(ERROR_BAD_ARGUMENTS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!((rv = ((HFDI) (*pfnalloc)(sizeof(FDI_Int)))))) {
|
||||
perf->erfOper = FDIERROR_ALLOC_FAIL;
|
||||
perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
|
||||
perf->fError = TRUE;
|
||||
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PFDI_INT(rv)->FDI_Intmagic = FDI_INT_MAGIC;
|
||||
PFDI_INT(rv)->pfnalloc = pfnalloc;
|
||||
PFDI_INT(rv)->pfnfree = pfnfree;
|
||||
PFDI_INT(rv)->pfnopen = pfnopen;
|
||||
PFDI_INT(rv)->pfnread = pfnread;
|
||||
PFDI_INT(rv)->pfnwrite = pfnwrite;
|
||||
PFDI_INT(rv)->pfnclose = pfnclose;
|
||||
PFDI_INT(rv)->pfnseek = pfnseek;
|
||||
/* no-brainer: we ignore the cpu type; this is only used
|
||||
for the 16-bit versions in Windows anyhow... */
|
||||
PFDI_INT(rv)->perf = perf;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* FDI_getoffset (internal)
|
||||
*
|
||||
* returns the file pointer position of a cab
|
||||
*/
|
||||
long FDI_getoffset(HFDI hfdi, INT_PTR hf)
|
||||
{
|
||||
return PFDI_SEEK(hfdi, hf, 0L, SEEK_CUR);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* FDI_realloc (internal)
|
||||
*
|
||||
* we can't use _msize; the user might not be using malloc, so we require
|
||||
* an explicit specification of the previous size. utterly inefficient.
|
||||
*/
|
||||
void *FDI_realloc(HFDI hfdi, void *mem, size_t prevsize, size_t newsize)
|
||||
{
|
||||
void *rslt = NULL;
|
||||
char *irslt, *imem;
|
||||
size_t copysize = (prevsize < newsize) ? prevsize : newsize;
|
||||
if (prevsize == newsize) return mem;
|
||||
rslt = PFDI_ALLOC(hfdi, newsize);
|
||||
if (rslt)
|
||||
for (irslt = (char *)rslt, imem = (char *)mem; (copysize); copysize--)
|
||||
*irslt++ = *imem++;
|
||||
PFDI_FREE(hfdi, mem);
|
||||
return rslt;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* FDI_read_string (internal)
|
||||
*
|
||||
* allocate and read an aribitrarily long string from the cabinet
|
||||
*/
|
||||
char *FDI_read_string(HFDI hfdi, INT_PTR hf, long cabsize)
|
||||
{
|
||||
size_t len=256,
|
||||
oldlen = 0,
|
||||
base = FDI_getoffset(hfdi, hf),
|
||||
maxlen = cabsize - base;
|
||||
BOOL ok = FALSE;
|
||||
int i;
|
||||
cab_UBYTE *buf = NULL;
|
||||
|
||||
TRACE("(hfdi == ^%p, hf == %d)\n", hfdi, hf);
|
||||
|
||||
do {
|
||||
if (len > maxlen) len = maxlen;
|
||||
if (!(buf = FDI_realloc(hfdi, buf, oldlen, len))) break;
|
||||
oldlen = len;
|
||||
if (!PFDI_READ(hfdi, hf, buf, len)) break;
|
||||
|
||||
/* search for a null terminator in what we've just read */
|
||||
for (i=0; i < len; i++) {
|
||||
if (!buf[i]) {ok=TRUE; break;}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
if (len == maxlen) {
|
||||
ERR("WARNING: cabinet is truncated\n");
|
||||
break;
|
||||
}
|
||||
len += 256;
|
||||
PFDI_SEEK(hfdi, hf, base, SEEK_SET);
|
||||
}
|
||||
} while (!ok);
|
||||
|
||||
if (!ok) {
|
||||
if (buf)
|
||||
PFDI_FREE(hfdi, buf);
|
||||
else
|
||||
ERR("out of memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* otherwise, set the stream to just after the string and return */
|
||||
PFDI_SEEK(hfdi, hf, base + ((cab_off_t) strlen((char *) buf)) + 1, SEEK_SET);
|
||||
|
||||
return (char *) buf;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* FDI_read_entries (internal)
|
||||
*
|
||||
* process the cabinet header in the style of FDIIsCabinet, but
|
||||
* without the sanity checks (and bug)
|
||||
*/
|
||||
BOOL FDI_read_entries(
|
||||
HFDI hfdi,
|
||||
INT_PTR hf,
|
||||
PFDICABINETINFO pfdici)
|
||||
{
|
||||
int num_folders, num_files, header_resv, folder_resv = 0;
|
||||
LONG base_offset, cabsize;
|
||||
USHORT setid, cabidx, flags;
|
||||
cab_UBYTE buf[64], block_resv;
|
||||
char *prevname, *previnfo, *nextname, *nextinfo;
|
||||
|
||||
TRACE("(hfdi == ^%p, hf == %d, pfdici == ^%p)\n", hfdi, hf, pfdici);
|
||||
|
||||
/* get basic offset & size info */
|
||||
base_offset = FDI_getoffset(hfdi, hf);
|
||||
|
||||
if (PFDI_SEEK(hfdi, hf, 0, SEEK_END) == -1) {
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
|
||||
PFDI_INT(hfdi)->perf->erfType = 0;
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cabsize = FDI_getoffset(hfdi, hf);
|
||||
|
||||
if ((cabsize == -1) || (base_offset == -1) ||
|
||||
( PFDI_SEEK(hfdi, hf, base_offset, SEEK_SET) == -1 )) {
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
|
||||
PFDI_INT(hfdi)->perf->erfType = 0;
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* read in the CFHEADER */
|
||||
if (!PFDI_READ(hfdi, hf, buf, cfhead_SIZEOF)) {
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
|
||||
PFDI_INT(hfdi)->perf->erfType = 0;
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check basic MSCF signature */
|
||||
if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) {
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
|
||||
PFDI_INT(hfdi)->perf->erfType = 0;
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* get the number of folders */
|
||||
num_folders = EndGetI16(buf+cfhead_NumFolders);
|
||||
if (num_folders == 0) {
|
||||
/* PONDERME: is this really invalid? */
|
||||
WARN("wierd cabinet detect failure: no folders in cabinet\n");
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
|
||||
PFDI_INT(hfdi)->perf->erfType = 0;
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* get the number of files */
|
||||
num_files = EndGetI16(buf+cfhead_NumFiles);
|
||||
if (num_files == 0) {
|
||||
/* PONDERME: is this really invalid? */
|
||||
WARN("wierd cabinet detect failure: no files in cabinet\n");
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
|
||||
PFDI_INT(hfdi)->perf->erfType = 0;
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* setid */
|
||||
setid = EndGetI16(buf+cfhead_SetID);
|
||||
|
||||
/* cabinet (set) index */
|
||||
cabidx = EndGetI16(buf+cfhead_CabinetIndex);
|
||||
|
||||
/* check the header revision */
|
||||
if ((buf[cfhead_MajorVersion] > 1) ||
|
||||
(buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
|
||||
{
|
||||
WARN("cabinet format version > 1.3\n");
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_UNKNOWN_CABINET_VERSION;
|
||||
PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* pull the flags out */
|
||||
flags = EndGetI16(buf+cfhead_Flags);
|
||||
|
||||
/* read the reserved-sizes part of header, if present */
|
||||
if (flags & cfheadRESERVE_PRESENT) {
|
||||
if (!PFDI_READ(hfdi, hf, buf, cfheadext_SIZEOF)) {
|
||||
WARN("bunk reserve-sizes?\n");
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
|
||||
PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
header_resv = EndGetI16(buf+cfheadext_HeaderReserved);
|
||||
folder_resv = buf[cfheadext_FolderReserved];
|
||||
block_resv = buf[cfheadext_DataReserved];
|
||||
|
||||
if (header_resv > 60000) {
|
||||
WARN("WARNING; header reserved space > 60000\n");
|
||||
}
|
||||
|
||||
/* skip the reserved header */
|
||||
if ((header_resv) && (PFDI_SEEK(hfdi, hf, header_resv, SEEK_CUR) == -1L)) {
|
||||
ERR("seek failure: header_resv\n");
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
|
||||
PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & cfheadPREV_CABINET) {
|
||||
prevname = FDI_read_string(hfdi, hf, cabsize);
|
||||
if (!prevname) {
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
|
||||
PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
previnfo = FDI_read_string(hfdi, hf, cabsize);
|
||||
}
|
||||
|
||||
if (flags & cfheadNEXT_CABINET) {
|
||||
nextname = FDI_read_string(hfdi, hf, cabsize);
|
||||
if (!nextname) {
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
|
||||
PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
nextinfo = FDI_read_string(hfdi, hf, cabsize);
|
||||
}
|
||||
|
||||
/* we could process the whole cabinet searching for problems;
|
||||
instead lets stop here. Now let's fill out the paperwork */
|
||||
pfdici->cbCabinet = cabsize;
|
||||
pfdici->cFolders = num_folders;
|
||||
pfdici->cFiles = num_files;
|
||||
pfdici->setID = setid;
|
||||
pfdici->iCabinet = cabidx;
|
||||
pfdici->fReserve = (flags & cfheadRESERVE_PRESENT) ? TRUE : FALSE;
|
||||
pfdici->hasprev = (flags & cfheadPREV_CABINET) ? TRUE : FALSE;
|
||||
pfdici->hasnext = (flags & cfheadNEXT_CABINET) ? TRUE : FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FDIIsCabinet (CABINET.21)
|
||||
|
@ -65,12 +350,41 @@ BOOL __cdecl FDIIsCabinet(
|
|||
INT_PTR hf,
|
||||
PFDICABINETINFO pfdici)
|
||||
{
|
||||
FIXME("(hfdi == ^%p, hf == ^%d, pfdici == ^%p): stub\n", hfdi, hf, pfdici);
|
||||
BOOL rv;
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
TRACE("(hfdi == ^%p, hf == ^%d, pfdici == ^%p)\n", hfdi, hf, pfdici);
|
||||
|
||||
if (!REALLY_IS_FDI(hfdi)) {
|
||||
ERR("REALLY_IS_FDI failed on ^%p\n", hfdi);
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!hf) {
|
||||
ERR("(!hf)!\n");
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
|
||||
PFDI_INT(hfdi)->perf->erfType = ERROR_INVALID_HANDLE;
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!pfdici) {
|
||||
ERR("(!pfdici)!\n");
|
||||
PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NONE;
|
||||
PFDI_INT(hfdi)->perf->erfType = ERROR_BAD_ARGUMENTS;
|
||||
PFDI_INT(hfdi)->perf->fError = TRUE;
|
||||
SetLastError(ERROR_BAD_ARGUMENTS);
|
||||
return FALSE;
|
||||
}
|
||||
rv = FDI_read_entries(hfdi, hf, pfdici);
|
||||
|
||||
if (rv)
|
||||
pfdici->hasnext = FALSE; /* yuck. duplicate apparent cabinet.dll bug */
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FDICopy (CABINET.22)
|
||||
*/
|
||||
|
@ -87,6 +401,11 @@ BOOL __cdecl FDICopy(
|
|||
pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p): stub\n",
|
||||
hfdi, pszCabinet, pszCabPath, flags, pfnfdin, pfnfdid, pvUser);
|
||||
|
||||
if (!REALLY_IS_FDI(hfdi)) {
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -96,14 +415,19 @@ BOOL __cdecl FDICopy(
|
|||
*/
|
||||
BOOL __cdecl FDIDestroy(HFDI hfdi)
|
||||
{
|
||||
FIXME("(hfdi == ^%p): stub\n", hfdi);
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
TRACE("(hfdi == ^%p)\n", hfdi);
|
||||
if (REALLY_IS_FDI(hfdi)) {
|
||||
PFDI_INT(hfdi)->FDI_Intmagic = 0; /* paranoia */
|
||||
PFDI_FREE(hfdi, hfdi); /* confusing, but correct */
|
||||
return TRUE;
|
||||
} else {
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FDICreate (CABINET.20)
|
||||
* FDITruncateCabinet (CABINET.24)
|
||||
*/
|
||||
BOOL __cdecl FDITruncateCabinet(
|
||||
HFDI hfdi,
|
||||
|
@ -113,7 +437,11 @@ BOOL __cdecl FDITruncateCabinet(
|
|||
FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
|
||||
hfdi, debugstr_a(pszCabinetName), iFolderToDelete);
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
|
||||
if (!REALLY_IS_FDI(hfdi)) {
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue