예제 #1
0
wchar_t *
StrToUnicode( const char *buf )
{
	wchar_t unibuf[1024];
	ASCIIToUnicode( buf, unibuf, sizeof(unibuf) );
	return _wcsdup( unibuf );
}
예제 #2
0
파일: xattr.c 프로젝트: 114577922/xpwn
int setAttribute(Volume* volume, uint32_t fileID, const char* name, uint8_t* data, size_t size) {
	HFSPlusAttrKey key;
	HFSPlusAttrData* record;
	int ret, exact;

	if(!volume->attrTree)
		return FALSE;

	memset(&key, 0 , sizeof(HFSPlusAttrKey));
	key.fileID = fileID;
	key.startBlock = 0;
	ASCIIToUnicode(name, &key.name);
	key.keyLength = sizeof(HFSPlusAttrKey) - sizeof(HFSUniStr255) + sizeof(key.name.length) + (sizeof(uint16_t) * key.name.length);

	record = (HFSPlusAttrData*) malloc(sizeof(HFSPlusAttrData) + size);
	memset(record, 0, sizeof(HFSPlusAttrData));

	record->recordType = kHFSPlusAttrInlineData;
	record->size = size;
	memcpy(record->data, data, size);

	ret = updateAttributes(volume, &key, (HFSPlusAttrRecord*) record);

	free(record);
	return ret;
}
예제 #3
0
파일: catalog.c 프로젝트: mucit/opensn0w
HFSPlusCatalogRecord* getLinkTarget(HFSPlusCatalogRecord* record, HFSCatalogNodeID parentID, HFSPlusCatalogKey *key, Volume* volume) {
	io_func* io;
	char pathBuffer[1024];
	HFSPlusCatalogRecord* toReturn;
	HFSPlusCatalogKey nkey;
	int exact;

	if(record->recordType == kHFSPlusFileRecord && (((HFSPlusCatalogFile*)record)->permissions.fileMode & S_IFLNK) == S_IFLNK) {
		io = openRawFile(((HFSPlusCatalogFile*)record)->fileID, &(((HFSPlusCatalogFile*)record)->dataFork), record, volume);
		READ(io, 0, (((HFSPlusCatalogFile*)record)->dataFork).logicalSize, pathBuffer);
		CLOSE(io);
		pathBuffer[(((HFSPlusCatalogFile*)record)->dataFork).logicalSize] = '\0';
		toReturn = getRecordFromPath3(pathBuffer, volume, NULL, key, TRUE, TRUE, parentID);
		free(record);
		return toReturn;
	} else if(record->recordType == kHFSPlusFileRecord && (((HFSPlusCatalogFile*)record)->userInfo.fileType) == kHardLinkFileType) {
		sprintf(pathBuffer, "iNode%d", ((HFSPlusCatalogFile*)record)->permissions.special.iNodeNum);
		nkey.parentID = volume->metadataDir;
    		ASCIIToUnicode(pathBuffer, &nkey.nodeName); 
		nkey.keyLength = sizeof(nkey.parentID) + sizeof(nkey.nodeName.length) + (sizeof(uint16_t) * nkey.nodeName.length);

		toReturn = (HFSPlusCatalogRecord*) search(volume->catalogTree, (BTKey*)(&nkey), &exact, NULL, NULL);

		free(record);

		return toReturn;
	} else {
		return record;
	}
}
예제 #4
0
파일: xattr.c 프로젝트: 114577922/xpwn
int unsetAttribute(Volume* volume, uint32_t fileID, const char* name) {
	HFSPlusAttrKey key;

	if(!volume->attrTree)
		return FALSE;

	memset(&key, 0 , sizeof(HFSPlusAttrKey));
	key.fileID = fileID;
	key.startBlock = 0;
	ASCIIToUnicode(name, &key.name);
	key.keyLength = sizeof(HFSPlusAttrKey) - sizeof(HFSUniStr255) + sizeof(key.name.length) + (sizeof(uint16_t) * key.name.length);
	return removeFromBTree(volume->attrTree, (BTKey*)(&key));
}
예제 #5
0
파일: xattr.c 프로젝트: 114577922/xpwn
size_t getAttribute(Volume* volume, uint32_t fileID, const char* name, uint8_t** data) {
	HFSPlusAttrKey key;
	HFSPlusAttrRecord* record;
	size_t size;
	int exact;

	if(!volume->attrTree)
		return FALSE;

	memset(&key, 0 , sizeof(HFSPlusAttrKey));
	key.fileID = fileID;
	key.startBlock = 0;
	ASCIIToUnicode(name, &key.name);
	key.keyLength = sizeof(HFSPlusAttrKey) - sizeof(HFSUniStr255) + sizeof(key.name.length) + (sizeof(uint16_t) * key.name.length);

	*data = NULL;

	record = (HFSPlusAttrRecord*) search(volume->attrTree, (BTKey*)(&key), &exact, NULL, NULL);

	if(exact == FALSE) {
		if(record)
			free(record);

		return 0;
	}

	switch(record->recordType)
	{
		case kHFSPlusAttrInlineData:
			size = record->attrData.size;
			*data = (uint8_t*) malloc(size);
			memcpy(*data, record->attrData.data, size);
			free(record);
			return size;
		default:
			fprintf(stderr, "unsupported attribute node format\n");
			return 0;
	}
}
예제 #6
0
파일: catalog.c 프로젝트: mucit/opensn0w
HFSCatalogNodeID newFolder(const char* pathName, Volume* volume) {
  HFSPlusCatalogFolder* parentFolder;
  HFSPlusCatalogFolder folder;
  HFSPlusCatalogKey key;
  HFSPlusCatalogThread thread;
  
  uint32_t newFolderID;
  
  int threadLength;
  
  char* path;
  char* name;
  char* curChar;
  char* lastSeparator;
  
  path = strdup(pathName);
  
  curChar = path;
  lastSeparator = NULL;
  
  while((*curChar) != '\0') {
    if((*curChar) == '/')
      lastSeparator = curChar;
    curChar++;
  }
  
  if(lastSeparator == NULL) {
    parentFolder = (HFSPlusCatalogFolder*) getRecordFromPath("/", volume, NULL, NULL);
    name = path;
  } else {
    name = lastSeparator + 1;
    *lastSeparator = '\0';
    parentFolder = (HFSPlusCatalogFolder*) getRecordFromPath(path, volume, NULL, NULL);  
  }

  if(parentFolder == NULL || parentFolder->recordType != kHFSPlusFolderRecord) {
    free(path);
    free(parentFolder);
    return FALSE;
  }
  
  newFolderID = volume->volumeHeader->nextCatalogID++;
  volume->volumeHeader->folderCount++;
  
  folder.recordType = kHFSPlusFolderRecord;
  folder.flags = kHFSHasFolderCountMask;
  folder.valence = 0;
  folder.folderID = newFolderID;
  folder.createDate = UNIX_TO_APPLE_TIME(time(NULL));
  folder.contentModDate = folder.createDate;
  folder.attributeModDate = folder.createDate;
  folder.accessDate = folder.createDate;
  folder.backupDate = folder.createDate;
  folder.permissions.ownerID = parentFolder->permissions.ownerID;
  folder.permissions.groupID = parentFolder->permissions.groupID;
  folder.permissions.adminFlags = 0;
  folder.permissions.ownerFlags = 0;
  folder.permissions.fileMode = S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
  folder.permissions.special.iNodeNum = 0;
  memset(&folder.userInfo, 0, sizeof(folder.userInfo));
  memset(&folder.finderInfo, 0, sizeof(folder.finderInfo));
  folder.textEncoding = 0;
  folder.folderCount = 0;
  
  key.parentID = parentFolder->folderID;
  ASCIIToUnicode(name, &key.nodeName);
  key.keyLength = sizeof(key.parentID) + STR_SIZE(key.nodeName);
  
  thread.recordType = kHFSPlusFolderThreadRecord;
  thread.reserved = 0;
  thread.parentID = parentFolder->folderID;
  ASCIIToUnicode(name, &thread.nodeName);
  threadLength = sizeof(thread.recordType) + sizeof(thread.reserved) + sizeof(thread.parentID) + STR_SIZE(thread.nodeName);
  flipCatalogThread(&thread, TRUE);
  flipCatalogFolder(&folder);
  
  ASSERT(addToBTree(volume->catalogTree, (BTKey*)(&key), sizeof(HFSPlusCatalogFolder), (unsigned char *)(&folder)), "addToBTree");
  key.nodeName.length = 0;
  key.parentID = newFolderID;
  key.keyLength = sizeof(key.parentID) + sizeof(key.nodeName.length);
  ASSERT(addToBTree(volume->catalogTree, (BTKey*)(&key), threadLength, (unsigned char *)(&thread)), "addToBTree");
  
  parentFolder->folderCount++;
  parentFolder->valence++;
  updateCatalog(volume, (HFSPlusCatalogRecord*) parentFolder);
  
  updateVolume(volume);
  
  free(parentFolder);
  free(path);
  
  return newFolderID;
}
예제 #7
0
파일: catalog.c 프로젝트: mucit/opensn0w
HFSPlusCatalogRecord* getRecordFromPath3(const char* path, Volume* volume, char **name, HFSPlusCatalogKey* retKey, char traverse, char returnLink, HFSCatalogNodeID parentID) {
  HFSPlusCatalogKey key;
  HFSPlusCatalogRecord* record;
  
  char* origPath;
  char* myPath;
  char* word;
  char* pathLimit;
  
  uint32_t realParent;
 
  int exact;
  
  if(path[0] == '\0' || (path[0] == '/' && path[1] == '\0')) {
    if(name != NULL)
      *name = (char*)path;
    
    key.keyLength = sizeof(key.parentID) + sizeof(key.nodeName.length);
    key.parentID = kHFSRootFolderID;
    key.nodeName.length = 0;
    
    record = (HFSPlusCatalogRecord*) search(volume->catalogTree, (BTKey*)(&key), &exact, NULL, NULL);
    key.parentID = ((HFSPlusCatalogThread*)record)->parentID;
    key.nodeName = ((HFSPlusCatalogThread*)record)->nodeName;
    
    free(record);
	
    record = (HFSPlusCatalogRecord*) search(volume->catalogTree, (BTKey*)(&key), &exact, NULL, NULL);
    return record;
  }
  
  myPath = strdup(path);
  origPath = myPath;
  
  record = NULL;

  if(path[0] == '/') {
    key.parentID = kHFSRootFolderID;
  } else {
    key.parentID = parentID;
  }

  pathLimit = myPath + strlen(myPath);
  
  for(word = (char*)strtok(myPath, "/"); word && (word < pathLimit);
      word = ((word + strlen(word) + 1) < pathLimit) ? (char*)strtok(word + strlen(word) + 1, "/") : NULL) {

    if(name != NULL)
      *name = (char*)(path + (word - origPath));
    
    if(record != NULL) {
      free(record);
      record = NULL;
    }
      
    if(word[0] == '\0') {
      continue;
    }

    ASCIIToUnicode(word, &key.nodeName);
    
    key.keyLength = sizeof(key.parentID) + sizeof(key.nodeName.length) + (sizeof(uint16_t) * key.nodeName.length);
    record = (HFSPlusCatalogRecord*) search(volume->catalogTree, (BTKey*)(&key), &exact, NULL, NULL);

    if(record == NULL || exact == FALSE) {
      free(origPath);
      if(record != NULL) {
	      free(record);
      }
      return NULL;
    }

    if(traverse) {
      if(((word + strlen(word) + 1) < pathLimit) || returnLink) {
        record = getLinkTarget(record, key.parentID, &key, volume);
        if(record == NULL || exact == FALSE) {
          free(origPath);
          return NULL;
        }
      }
    }
	
    if(record->recordType == kHFSPlusFileRecord) {	
	if((word + strlen(word) + 1) >= pathLimit) {
		free(origPath);
      
		if(retKey != NULL) {
			memcpy(retKey, &key, sizeof(HFSPlusCatalogKey));
		}
      
		return record;
	} else {
		free(origPath);
		free(record);
		return NULL;
	}
    }
    
    if(record->recordType != kHFSPlusFolderRecord)
      hfs_panic("inconsistent catalog tree!");
    
    realParent = key.parentID;
    key.parentID = ((HFSPlusCatalogFolder*)record)->folderID;
  }
  
  if(retKey != NULL) {
    memcpy(retKey, &key, sizeof(HFSPlusCatalogKey));
    retKey->parentID = realParent;
  }
  
  free(origPath);
  return record;
}
예제 #8
0
파일: catalog.c 프로젝트: mucit/opensn0w
CatalogRecordList* getFolderContents(HFSCatalogNodeID CNID, Volume* volume) {
	BTree* tree;
	HFSPlusCatalogThread* record; 
	HFSPlusCatalogKey key;
	uint32_t nodeNumber;
	int recordNumber;

	BTNodeDescriptor* descriptor;
	off_t recordOffset;
	off_t recordDataOffset;
	HFSPlusCatalogKey* currentKey;

	CatalogRecordList* list;
	CatalogRecordList* lastItem;
	CatalogRecordList* item;

	char pathBuffer[1024];
	HFSPlusCatalogRecord* toReturn;
	HFSPlusCatalogKey nkey;
	int exact;

	tree = volume->catalogTree;

	key.keyLength = sizeof(key.parentID) + sizeof(key.nodeName.length);
	key.parentID = CNID;
	key.nodeName.length = 0;

	list = NULL;

	record = (HFSPlusCatalogThread*) search(tree, (BTKey*)(&key), NULL, &nodeNumber, &recordNumber);

	if(record == NULL)
		return NULL;

	free(record);

	++recordNumber;

	while(nodeNumber != 0) {    
		descriptor = readBTNodeDescriptor(nodeNumber, tree);

		while(recordNumber < descriptor->numRecords) {
			recordOffset = getRecordOffset(recordNumber, nodeNumber, tree);
			currentKey = (HFSPlusCatalogKey*) READ_KEY(tree, recordOffset, tree->io);
			recordDataOffset = recordOffset + currentKey->keyLength + sizeof(currentKey->keyLength);

			if(currentKey->parentID == CNID) {
				item = (CatalogRecordList*) malloc(sizeof(CatalogRecordList));
				item->name = currentKey->nodeName;
				item->record = (HFSPlusCatalogRecord*) READ_DATA(tree, recordDataOffset, tree->io);

				if(item->record->recordType == kHFSPlusFileRecord && (((HFSPlusCatalogFile*)item->record)->userInfo.fileType) == kHardLinkFileType) {
					sprintf(pathBuffer, "iNode%d", ((HFSPlusCatalogFile*)item->record)->permissions.special.iNodeNum);
					nkey.parentID = volume->metadataDir;
					ASCIIToUnicode(pathBuffer, &nkey.nodeName); 
					nkey.keyLength = sizeof(nkey.parentID) + sizeof(nkey.nodeName.length) + (sizeof(uint16_t) * nkey.nodeName.length);

					toReturn = (HFSPlusCatalogRecord*) search(volume->catalogTree, (BTKey*)(&nkey), &exact, NULL, NULL);

					free(item->record);
					item->record = toReturn;
				}
				item->next = NULL;

				if(list == NULL) {
					list = item;
				} else {
					lastItem->next = item;
				}

				lastItem = item;
				free(currentKey);
			} else {
				free(currentKey);
				free(descriptor);
				return list;
			}

			recordNumber++;
		}

		nodeNumber = descriptor->fLink;
		recordNumber = 0;

		free(descriptor);
	}

	return list;
}