//---------------------------- CMD_DosEnumAttribute ---------------------------- void CMD_DosEnumAttribute(HFILE hFile,LXIOCPA_DMN_CMDPARMPACKET* pParam ,PLXDOSENUMATTRIBUTESTRUCT pea) { void* pBuffer=(void*)(((unsigned long)pea)+sizeof(LXDOSENUMATTRIBUTESTRUCT)); pParam->rc=DosEnumAttribute(pea->ulRefType,&pea->vFile,pea->ulEntry ,pBuffer,pea->cbBuf,&pea->ulCount ,pea->ulInfoLevel); }
/*@ XFile::GetEAList ( char*, XEAList* ) @group EAs @parameters <t 'ø' c=2> øchar * fileName øname of the file øXEAList* list øbuffer of type XEAList </t> @returns ULONG result @remarks Read all EAs of a file. */ ULONG XFile :: GetEAList( const char * path, XEAList * eaList) { UCHAR buffer[500] = {0}; ULONG ulEnumCnt = 0; FEA2 *ptr = NULL; ULONG ulTemp = 0; ULONG rc; ulEnumCnt = (ULONG)-1; rc = DosEnumAttribute(ENUMEA_REFTYPE_PATH, (PSZ) (char*) path, 1L, (PVOID)&buffer, sizeof(buffer), &ulEnumCnt, ENUMEA_LEVEL_NO_VALUE); if (rc == 0) { eaList->ClearList(); eaList->count = ulEnumCnt; eaList->list = (XEA**) malloc( ulEnumCnt * sizeof(void*)); ptr = (FEA2 *)buffer; for ( int i = 0; i < ulEnumCnt; i++) { eaList->list[i] = new XEA(); eaList->list[i]->name = ptr->szName; ulTemp = ptr->oNextEntryOffset + (ULONG)ptr; ptr = (FEA2 *)ulTemp; } } else return rc; for( int i = 0; i < ulEnumCnt; i++) { rc = XFile::GetEA( path, eaList->list[i], eaList->list[i]->name); if(rc) return rc; } return 0; }
unsigned long SysQueryEAList(unsigned char *name, unsigned long numargs, RXSTRING args[], char *queuename, RXSTRING *retstr) { int countEA = 0; unsigned long rc; unsigned long act; unsigned long numberEA; unsigned long offset = 0; char szStemName[256] = {0}; char fileName[512] = {0}; char *pszStemIdx = NULL; char buffer[EABUFFER]; char eanum[5]; FEA2 *ptrBuffer; FILESTATUS3 status; HFILE handle; /* Only two arguments accepted */ if (numargs != 2 || !RXVALIDSTRING(args[0]) || !RXVALIDSTRING(args[1]) || args[0].strlength > 255) return INVALID_ROUTINE; /* remember stem name */ strcpy(szStemName, args[1].strptr); strupr(szStemName); strcpy(fileName, args[0].strptr); // check for '.' and if not there make it so if (szStemName[args[1].strlength-1] != '.') szStemName[args[1].strlength] = '.'; // pointer to the index part of stem pszStemIdx = &(szStemName[strlen(szStemName)]); // query to find if it is a file or directory if(DosQueryPathInfo(fileName, FIL_STANDARD, (void *)&status, sizeof(status))) return INVALID_ROUTINE; // if it is a file open it if(!(status.attrFile&FILE_DIRECTORY)) { if(DosOpen(fileName, &handle, &act, 0L, 0, FILE_OPEN, OPEN_ACCESS_READONLY + OPEN_SHARE_DENYWRITE + OPEN_FLAGS_FAIL_ON_ERROR, NULL)) return INVALID_ROUTINE; } numberEA = (ULONG)-1; rc = DosEnumAttribute(ENUMEA_REFTYPE_PATH, fileName, 1, (PVOID)&buffer, EABUFFER, (ULONG *)&numberEA, ENUMEA_LEVEL_NO_VALUE); if(rc) RETVAL(0) // if it is a file - close it if (!(status.attrFile&FILE_DIRECTORY)) DosClose(handle); ptrBuffer = (FEA2 *)&buffer; // set pointer to statrt of buffer if(numberEA != 0) { // if there are EAs found do { ptrBuffer = (PDENA2)((char *)ptrBuffer + offset); itoa(++countEA, pszStemIdx, 10); rc = SetRexxVariable(szStemName, ptrBuffer->szName); offset = ptrBuffer->oNextEntryOffset; } while ( ptrBuffer->oNextEntryOffset != 0 ); } // end of handling EAs // setup the 0 index with number of classes strcpy(pszStemIdx, "0"); sprintf(eanum, "%d", numberEA); rc = SetRexxVariable(szStemName, eanum); RETVAL(1); }
int _ead_enum (struct _ead_data *ead, char *path, int handle, int (*function)(struct _ead_data *ead, PDENA2 pdena, void *arg), void *arg) { void *dena_buf; void *fileref; ULONG dena_buf_size, index, count, rc, reftype, hf, i; PDENA2 pdena; int expand_dena_buf; if (path != NULL) { reftype = ENUMEA_REFTYPE_PATH; fileref = path; } else { hf = handle; reftype = ENUMEA_REFTYPE_FHANDLE; fileref = &hf; } dena_buf_size = 0; dena_buf = NULL; expand_dena_buf = 1; index = 1; for (;;) { if (expand_dena_buf) { dena_buf_size += 0x20000; /* DosEnumAttribute is broken */ dena_buf = realloc (dena_buf, dena_buf_size); if (dena_buf == NULL) { errno = ENOMEM; return -1; } } count = -1; rc = DosEnumAttribute (reftype, fileref, index, dena_buf, dena_buf_size, &count, ENUMEA_LEVEL_NO_VALUE); if (rc == ERROR_BUFFER_OVERFLOW) expand_dena_buf = 1; else if (rc != 0) { free (dena_buf); _ea_set_errno (rc); return -1; } else if (count == 0) break; else { expand_dena_buf = 0; pdena = dena_buf; for (i = 0; i < count; ++i) { if (function (ead, pdena, arg) < 0) { free (dena_buf); return -1; } pdena = (PDENA2)((char *)pdena + pdena->oNextEntryOffset); } index += count; } } free (dena_buf); return 0; }
int query_ea(char FAR **dest, char *name, int skip_ln) { #ifdef HAVE_EAS ULONG count, j; #if TARGET==OS2 #ifdef __32BIT__ EAOP2 eaop; PGEA2LIST pgeal; PFEA2LIST pfeal; APIRET rc; PDENA2 pdena; FILESTATUS4 fs; #else EAOP eaop; PGEALIST pgeal; PFEALIST pfeal; USHORT rc; PDENA1 pdena; FILESTATUS2 fs; #endif #elif TARGET==WIN32 struct nt_sid *sid; unsigned char *streambuf; unsigned long stream_len; PFEALIST pfeal; #endif int rcode=0; char FAR *dptr, FAR *nptr; #if TARGET==OS2 pdena=farmalloc_msg(sizeof(*pdena)+CCHMAXPATHCOMP); #ifdef __32BIT__ pgeal=(PGEA2LIST)farmalloc_msg(sizeof(GEA2LIST)+CCHMAXPATHCOMP); if(DosQueryPathInfo(name, FIL_QUERYEASIZE, (PVOID)&fs, sizeof(fs))) return(-1); #else pgeal=(PGEALIST)farmalloc_msg(sizeof(GEALIST)+CCHMAXPATHCOMP); if(DosQPathInfo(name, FIL_QUERYEASIZE, (PVOID)&fs, sizeof(fs), 0L)) return(-1); #endif if(fs.cbList<4) fs.cbList=4; /* Fix for Ext2FS */ /* Allocate enough space to hold EA block */ #ifdef __32BIT__ *dest=(char FAR *)farmalloc_msg((int)fs.cbList*2); /* SDK does recommend it */ #else *dest=(char FAR *)farmalloc_msg((int)fs.cbList-2); #endif #elif TARGET==WIN32 if((sid=open_streams(name, 0))==NULL) return(-1); stream_len=seek_stream_id(BACKUP_EA_DATA, sid); if(stream_len==0||stream_len>65535) { close_streams(sid); *dest=(char FAR *)farmalloc_msg(2); dptr=*dest; mput_word(0, dptr); return(0); } /* It's a plain FEALIST, so doesn't require much caution */ streambuf=(char FAR *)farmalloc_msg((int)stream_len); *dest=(char FAR *)farmalloc_msg((int)stream_len); if((stream_len=read_stream(streambuf, stream_len, sid))==0) { close_streams(sid); dptr=*dest; mput_word(0, dptr); free(streambuf); return(0); } #endif /* Initialize storage */ dptr=*dest; mput_word(0, dptr); dptr+=2; j=0L; while(1) { #if TARGET==OS2 count=1L; #ifdef __32BIT__ if(DosEnumAttribute(ENUMEA_REFTYPE_PATH, (PVOID)name, ++j, (PVOID)pdena, sizeof(*pdena)+CCHMAXPATHCOMP, &count, ENUMEA_LEVEL_NO_VALUE)) break; #else if(DosEnumAttribute(ENUMEA_REFTYPE_PATH, (PVOID)name, ++j, (PVOID)pdena, sizeof(*pdena)+CCHMAXPATHCOMP, &count, ENUMEA_LEVEL_NO_VALUE, 0L)) break; #endif if(count==0L) break; /* EA (pdena->szName) consumes (pdena->cbValue) bytes */ #ifdef __32BIT__ eaop.fpGEA2List=pgeal; #else eaop.fpGEAList=pgeal; #endif far_strcpy(pgeal->list[0].szName, pdena->szName); pgeal->list[0].cbName=pdena->cbName; #ifdef __32BIT__ pgeal->list[0].oNextEntryOffset=0; pgeal->cbList=sizeof(GEA2LIST)+pdena->cbName; eaop.fpGEA2List=pgeal; pfeal=(PFEA2LIST)farmalloc_msg(sizeof(FEA2LIST)+pdena->cbName+pdena->cbValue+1); pfeal->cbList=sizeof(FEA2LIST)+pdena->cbName+pdena->cbValue+1; eaop.fpFEA2List=pfeal; if((rc=DosQueryPathInfo(name, FIL_QUERYEASFROMLIST, (PBYTE)&eaop, sizeof(eaop)))!=0) { farfree(pfeal); rcode=-1; break; } nptr=(char FAR *)&(pfeal->list[0])+sizeof(FEA2)-1; #else pgeal->cbList=sizeof(GEALIST)+pdena->cbName; eaop.fpGEAList=pgeal; pfeal=(PFEALIST)farmalloc_msg(sizeof(FEALIST)+pdena->cbName+pdena->cbValue+1); pfeal->cbList=sizeof(FEALIST)+pdena->cbName+pdena->cbValue+1; eaop.fpFEAList=pfeal; if((rc=DosQPathInfo(name, FIL_QUERYEASFROMLIST, (PBYTE)&eaop, sizeof(eaop), 0L))!=0) { farfree(pfeal); rcode=-1; break; } nptr=(char FAR *)&(pfeal->list[0])+sizeof(FEA); #endif #elif TARGET==WIN32 /* Win32 provides us with a FEALIST at our disposal. */ pfeal=(PFEALIST)streambuf; nptr=(char FAR *)&(pfeal->list[0])+sizeof(FEA); #endif #if SFX_LEVEL>=ARJ if(ea_filter(nptr, skip_ln)&&((pfeal->list[0].fEA&FEA_NEEDEA)||!crit_eas)) #endif { mput_word(mget_word(*dest)+1, *dest); mput_byte(pfeal->list[0].fEA, dptr++); mput_byte(pfeal->list[0].cbName, dptr++); mput_word(pfeal->list[0].cbValue, dptr); dptr+=2; far_memmove(dptr, nptr, (int)pfeal->list[0].cbName); dptr+=pfeal->list[0].cbName; far_memmove(dptr, nptr+pfeal->list[0].cbName+1, pfeal->list[0].cbValue); dptr+=pfeal->list[0].cbValue; } #if TARGET==OS2 farfree(pfeal); #elif TARGET==WIN32 if(pfeal->cbList==0) /* Indicates the last EA */ break; streambuf+=pfeal->cbList; #endif } #if TARGET==OS2 farfree(pdena); farfree(pgeal); #endif #if TARGET==WIN32 close_streams(sid); #endif return(rcode); #else return(-1); #endif }
int discard_ea(char *name) { #if TARGET==OS2 ULONG count; #ifdef __32BIT__ APIRET rc; char FAR *real_pfeal; PFEA2LIST pfeal; EAOP2 eaop; PDENA2 pdena; #else USHORT rc; PFEALIST pfeal; EAOP eaop; PDENA1 pdena; #endif int rcode=0; #ifdef __32BIT__ pdena=(PDENA2)farmalloc_msg(sizeof(*pdena)+CCHMAXPATHCOMP); real_pfeal=(char FAR *)farmalloc_msg(sizeof(*pdena)+CCHMAXPATHCOMP); pfeal=(PFEA2LIST)align_dword(real_pfeal); #else pdena=(PDENA1)farmalloc_msg(sizeof(*pdena)+CCHMAXPATHCOMP); pfeal=(PFEALIST)farmalloc_msg(sizeof(*pdena)+CCHMAXPATHCOMP); #endif while(1) { count=1L; #ifdef __32BIT__ if(DosEnumAttribute(ENUMEA_REFTYPE_PATH, (PVOID)name, 1L, (PVOID)pdena, sizeof(*pdena)+CCHMAXPATHCOMP, &count, ENUMEA_LEVEL_NO_VALUE)) #else if(DosEnumAttribute(ENUMEA_REFTYPE_PATH, (PVOID)name, 1L, (PVOID)pdena, sizeof(*pdena)+CCHMAXPATHCOMP, &count, ENUMEA_LEVEL_NO_VALUE, 0L)) #endif break; if(count==0L) break; /* EA (pdena->szName) consumes (pdena->cbValue) bytes */ #ifdef __32BIT__ eaop.fpFEA2List=pfeal; pfeal->list[0].oNextEntryOffset=0; #else eaop.fpFEAList=pfeal; #endif pfeal->list[0].fEA=0; pfeal->list[0].cbName=far_strlen(pdena->szName); pfeal->list[0].cbValue=0; #ifdef __32BIT__ far_strcpy((char FAR *)&(pfeal->list[0])+sizeof(FEA2)-1, pdena->szName); pfeal->cbList=(unsigned long)sizeof(FEA2LIST)+pfeal->list[0].cbName; if((rc=DosSetPathInfo(name, FIL_QUERYEASIZE, (PBYTE)&eaop, sizeof(eaop), 0))!=0) { rcode=-1; break; } #else far_strcpy((char FAR *)&(pfeal->list[0])+sizeof(FEA), pdena->szName); pfeal->cbList=(unsigned long)sizeof(FEALIST)+pfeal->list[0].cbName+1; if((rc=DosSetPathInfo(name, FIL_QUERYEASIZE, (PBYTE)&eaop, sizeof(eaop), 0, 0L))!=0) { rcode=-1; break; } #endif } farfree(pdena); #ifndef TILED farfree(real_pfeal); #endif return(rcode); #elif TARGET==WIN32 /* There seems to be no easy way to not purge EAs using the backup APIs! */ return(0); #else return(-1); #endif }
void _Optlink dump_ea(PSZ pszFile, PSZ pszEAFile, char **apszNames, ULONG ulNames) { APIRET rc = NO_ERROR; ULONG cbList = 0; EAOP2 eaop2 = { NULL, NULL, 0UL }; ULONG cbEABuf = 0; /* * Get a buffer size which will be used to ensure that no EA:s are lost. */ cbList = queryEASize(pszFile); if(cbList == 0) { return; } eaop2.fpFEA2List = malloc(cbList); if(eaop2.fpFEA2List) { ULONG ulCount = (ULONG)-1; /* * Get list of EA names. This does not get a real FEA2 list, it gets something called a * DENA2, which should be used for two things only: 1) Get EA names, 2) Get EA sizes. */ rc = DosEnumAttribute(ENUMEA_REFTYPE_PATH, pszFile, 1UL, &eaop2.fpFEA2List->list[0], cbList, &ulCount, ENUMEA_LEVEL_NO_VALUE); if(rc == NO_ERROR) { FEA2 *pfea2 = (FEA2*)&eaop2.fpFEA2List->list[0]; PBYTE p = NULL; ULONG i = 0; GEA2 *pGEA2Cursor = NULL; /* Pointer used while adding GEA2 entries */ /* * Init and set up Get EA list */ eaop2.fpGEA2List = malloc(cbList); memset(eaop2.fpGEA2List, 0, cbList); /* Important! */ eaop2.fpGEA2List->cbList = sizeof(eaop2.fpGEA2List->cbList); /* * Set up GEA2 cursor for adding GEA2 entries */ pGEA2Cursor = &eaop2.fpGEA2List->list[0]; /* * Loop through all EA names fetched with DosEnumAttribute() and add them * to the GEA2 list, unless they are in the filter-list ofcourse. */ for(i = 0; i < ulCount; i++) { ULONG iFilter = 0; BOOL fFilter = FALSE; /* Don't filter by default */ /* * Ugh, slow search.. */ for(iFilter = 0; iFilter < ulNames; iFilter++) { if(strcmp(pfea2->szName, apszNames[iFilter]) == 0) { /* * EA name is in filter-list, set filter boolean to true, and * break out of loop. */ fFilter = TRUE; break; } } if(!fFilter) { /* * EA name is not in the filter-list, add it to the Get EA list. */ if(pGEA2Cursor->cbName) { PBYTE pTmp = (PBYTE)pGEA2Cursor; /* * Note; the GEA2 entries *must* be 4-byte (double word) aligned */ pGEA2Cursor->oNextEntryOffset = sizeof(GEA2)+pfea2->cbName; pGEA2Cursor->oNextEntryOffset += (4-(pGEA2Cursor->oNextEntryOffset%4)); pTmp += pGEA2Cursor->oNextEntryOffset; pGEA2Cursor = (GEA2*)pTmp; } pGEA2Cursor->oNextEntryOffset = 0; pGEA2Cursor->cbName = pfea2->cbName; memcpy(pGEA2Cursor->szName, pfea2->szName, pfea2->cbName+1); /* * Calculate EA buffer size (used for storing EA buffer). * The EA buffer file EAUTIL uses does not include the * oNextENtryOffset parameter, so don't include it here. */ if(cbEABuf == 0) { /* Intially add size long word */ cbEABuf += sizeof(eaop2.fpFEA2List->cbList); } cbEABuf += (sizeof(pfea2->fEA) + sizeof(pfea2->cbName) + sizeof(pfea2->cbValue) + (pfea2->cbName+1) + pfea2->cbValue); eaop2.fpGEA2List->cbList += (sizeof(GEA2)+pGEA2Cursor->cbName); if(eaop2.fpGEA2List->cbList % 4) { eaop2.fpGEA2List->cbList += (4-(eaop2.fpGEA2List->cbList%4)); } } p = pfea2->oNextEntryOffset + (PBYTE)pfea2; pfea2 = (FEA2*)p; } /* * Check if calculated EA buffer size. If it is non-zero, one or more GEA2 entries * should be read. */ if(cbEABuf) { /* * Reset the eaop2.fpFEA2List->cbList value so the EA API knows it has enough * memory for the FEA2 list. */ eaop2.fpFEA2List->cbList = cbList; /* * Get the FEA2 list from the GEA2 list. */ rc = DosQueryPathInfo(pszFile, FIL_QUERYEASFROMLIST, &eaop2, sizeof(EAOP2)); if(rc == NO_ERROR) { HFILE hFile = NULLHANDLE; ULONG ulAction = 0; const ULONG fsOpenFlags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS; const ULONG fsOpenMode = OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYWRITE | OPEN_ACCESS_WRITEONLY; rc = DosOpen(pszEAFile, &hFile, &ulAction, 0UL, FILE_NORMAL, fsOpenFlags, fsOpenMode, NULL); if(rc == NO_ERROR) { ULONG cbWritten = 0; ULONG ibActual = 0; /* * The cbEABuf should by now contain the size of the EA buffer. */ eaop2.fpFEA2List->cbList = cbEABuf; rc = DosWrite(hFile, &eaop2.fpFEA2List->cbList, sizeof(eaop2.fpFEA2List->cbList), &cbWritten); pfea2 = &eaop2.fpFEA2List->list[0]; while(1) { PBYTE pWriteBuf = (PBYTE)pfea2 + sizeof(pfea2->oNextEntryOffset); /* Skip the oNextEntryOffset long word */ /* * Write the FEA2 structure, but skip oNextEntryOffset */ rc = DosWrite(hFile, pWriteBuf, sizeof(FEA2)-sizeof(pfea2->oNextEntryOffset)+pfea2->cbName+pfea2->cbValue, &cbWritten); if(pfea2->oNextEntryOffset == 0) { /* * Break out of loop if this entry is the last node */ break; } /* Next FEA2 entry */ p = pfea2->oNextEntryOffset + (PBYTE)pfea2; pfea2 = (FEA2*)p; } rc = DosClose(hFile); } } } free(eaop2.fpFEA2List); } } free(eaop2.fpGEA2List); }