예제 #1
0
static PyObject *
	Package_getitemtype(PackageObject *self, PyObject *args)
{
	hlChar *lpPath;
	HLDirectoryItem *pItem = 0;

	PyObject *v;

	if (!PyArg_ParseTuple(args, "s", &lpPath))
	{
		return NULL;
	}

	// Find the item.
	pItem = hlFolderGetItemByPath(hlPackageGetRoot(), lpPath, HL_FIND_ALL);
	if(pItem == 0)
	{
		PyErr_SetString(PyExc_ValueError, "x not found in package.\n");
		return NULL;
	}

	
	// Get type and return it
	v = Py_BuildValue("i", hlItemGetType(pItem));
    if (v == NULL) {
        return NULL;
    }

	return v;
}
예제 #2
0
static PyObject *
	Package_extract(PackageObject *self, PyObject *args)
{
	hlUInt i;

	hlUInt uiExtractItems = 0;
	hlChar *lpExtractItems[MAX_ITEMS];
	hlChar *lpDestination = 0;;

	HLDirectoryItem *pItem = 0;

	pUpdateFunc = Py_None;

	if (!PyArg_ParseTuple(args, "ss|O", &lpExtractItems[0], &lpDestination, &pUpdateFunc))
	{
		return NULL;
	}

	uiExtractItems = 1;

	// Just before extracting set these globals
	hlSetBoolean(HL_OVERWRITE_FILES, self->bOverwriteFiles);
	hlSetBoolean(HL_FORCE_DEFRAGMENT, self->bForceDefragment);
	bSilent = self->bSilent;

	// Extract the requested items.
	for(i = 0; i < uiExtractItems; i++)
	{
		// Find the item.
		pItem = hlFolderGetItemByPath(hlPackageGetRoot(), lpExtractItems[i], HL_FIND_ALL);

		if(pItem == 0)
		{
			PySys_WriteStdout("%s not found in package.\n", lpExtractItems[i]);
			continue;
		}

		if(!self->bSilent)
		{
			PySys_WriteStdout("Extracting %s...\n\n", hlItemGetName(pItem));
		}

		// Extract the item.
		// Item is extracted to cDestination\Item->GetName().
		g_extract_save = PyEval_SaveThread();
		g_bytesExtracted = 0;
		hlItemExtract(pItem, lpDestination);
		PyEval_RestoreThread(g_extract_save);

		if(!self->bSilent)
		{
			PySys_WriteStdout("\nDone.\n");
		}
	}

	Py_INCREF(Py_None);
	return Py_None;
}
예제 #3
0
static PyObject *
	Package_listdir(PackageObject *self, PyObject *args)
{
	hlUInt i, iCount;
	hlChar *lpPath;
	const hlChar *lpItemName;

	HLDirectoryItem *pItem = 0;
	HLDirectoryItem *pSubItem = 0;

	PyObject *d, *v;

	if (!PyArg_ParseTuple(args, "s", &lpPath))
	{
		return NULL;
	}

	// Find the item.
	pItem = hlFolderGetItemByPath(hlPackageGetRoot(), lpPath, HL_FIND_ALL);
	if(pItem == 0)
	{
		PyErr_SetString(PyExc_ValueError, "x not found in package.\n");
		return NULL;
	}

	// Allocate a list
    if ((d = PyList_New(0)) == NULL) {
        return NULL;
    }

	// List items
	iCount = hlFolderGetCount(pItem);
	for( i = 0; i < iCount; i++ )
	{
		pSubItem = hlFolderGetItem(pItem, i);
		lpItemName = hlItemGetName(pSubItem);

		v = PyString_FromString(lpItemName);
        if (v == NULL) {
            Py_DECREF(d);
            d = NULL;
            break;
        }
        if (PyList_Append(d, v) != 0) {
            Py_DECREF(v);
            Py_DECREF(d);
            d = NULL;
            break;
        }
        Py_DECREF(v);
	}

	return d;
}
예제 #4
0
static PyObject *
	Package_validate(PackageObject *self, PyObject *args)
{
	hlUInt i;

	hlUInt uiValidateItems = 0;
	hlChar *lpValidateItems[MAX_ITEMS];

	HLDirectoryItem *pItem = 0;

	if (!PyArg_ParseTuple(args, "s", &lpValidateItems[0]))
	{
		return NULL;
	}

	uiValidateItems = 1;

	// Validate the requested items.
	for(i = 0; i < uiValidateItems; i++)
	{
		// Find the item.
		pItem = hlFolderGetItemByPath(hlPackageGetRoot(), lpValidateItems[i], HL_FIND_ALL);

		if(pItem == 0)
		{
			printf("%s not found in package.\n", lpValidateItems[i]);
			continue;
		}

		if(!self->bSilent)
		{
			PySys_WriteStdout("Validating %s...\n\n", hlItemGetName(pItem));
		}

		// Validate the item.
		Validate(self, pItem);

		if(!self->bSilent)
		{
			PySys_WriteStdout("\nDone.\n");
		}
	}

	Py_INCREF(Py_None);
	return Py_None;
}
예제 #5
0
파일: Main.c 프로젝트: Rupan/HLLib
hlVoid EnterConsole(hlUInt uiPackage, hlUInt uiConsoleCommands, hlChar *lpConsoleCommands[])
{
    hlUInt i;

    hlChar lpBuffer[BUFFER_SIZE];	// Input string.
    hlChar lpCommand[BUFFER_SIZE];	// Input command  (i.e. first word in input string).
    hlChar lpArgument[BUFFER_SIZE];	// Input argument (i.e. rest of input string).
    hlChar *lpTemp;
    hlChar lpTempBuffer[BUFFER_SIZE];

    hlUInt16 uiColor;
    HLDirectoryItem *pItem = 0, *pSubItem = 0;

    hlBool bFound;
    hlUInt uiItemCount, uiFolderCount, uiFileCount;
    hlChar iChar;
    HLStream *pStream = 0;
    HLAttribute Attribute;
    HLPackageType ePackageType = HL_PACKAGE_NONE;
    hlUInt uiSubPackage = HL_ID_INVALID;

    pItem = hlPackageGetRoot();

    while(hlTrue)
    {
        uiColor = GetColor();
        SetColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);

        if(uiConsoleCommands > 0)
        {
            printf("%s>%s\n", hlItemGetName(pItem), *lpConsoleCommands);

            strncpy(lpBuffer, *lpConsoleCommands, sizeof(lpBuffer));
            lpBuffer[sizeof(lpBuffer) - 1] = '\0';

            uiConsoleCommands--;
            lpConsoleCommands++;
        }
        else
        {
            // Command prompt.
            printf("%s>", hlItemGetName(pItem));

            // Get and parse line.
            fgets(lpBuffer, sizeof(lpBuffer), stdin);
        }

        SetColor(uiColor);

        i = (hlUInt)strlen(lpBuffer);
        while(i > 0 && (lpBuffer[i - 1] == '\r' || lpBuffer[i - 1] == '\n'))
        {
            i--;
            lpBuffer[i] = '\0';
        }

        *lpCommand = *lpArgument = 0;

        strcpy(lpCommand, lpBuffer);
        lpTemp = strchr(lpCommand, ' ');
        if(lpTemp != 0)
        {
            strcpy(lpArgument, lpTemp + 1);
            *lpTemp = 0;
        }

        // Cycle through commands.

        //
        // Directory listing.
        // Good example of CDirectoryItem::GetType().
        //
#ifdef _WIN32
        if(stricmp(lpCommand, "dir") == 0)
#else
        if(stricmp(lpCommand, "ls") == 0)
#endif
        {
            uiItemCount = hlFolderGetCount(pItem);
            uiFolderCount = 0, uiFileCount = 0;

            *lpTempBuffer = 0;
            hlItemGetPath(pItem, lpTempBuffer, sizeof(lpTempBuffer));

            printf("Directory of %s:\n", lpTempBuffer);

            printf("\n");

            if(*lpArgument == 0)
            {
                // List all items in the current folder.
                for(i = 0; i < uiItemCount; i++)
                {
                    pSubItem = hlFolderGetItem(pItem, i);
                    if(hlItemGetType(pSubItem) == HL_ITEM_FOLDER)
                    {
                        uiFolderCount++;
                        printf("  <%s>\n", hlItemGetName(pSubItem));
                    }
                    else if(hlItemGetType(pSubItem) == HL_ITEM_FILE)
                    {
                        uiFileCount++;
                        printf("  %s\n", hlItemGetName(pSubItem));
                    }
                }
            }
            else
            {
                pSubItem = hlFolderFindFirst(pItem, lpArgument, HL_FIND_ALL | HL_FIND_NO_RECURSE);
                while(pSubItem)
                {
                    if(hlItemGetType(pSubItem) == HL_ITEM_FOLDER)
                    {
                        uiFolderCount++;
                        printf("  <%s>\n", hlItemGetName(pSubItem));
                    }
                    else if(hlItemGetType(pSubItem) == HL_ITEM_FILE)
                    {
                        uiFileCount++;
                        printf("  %s\n", hlItemGetName(pSubItem));
                    }

                    pSubItem = hlFolderFindNext(pItem, pSubItem, lpArgument, HL_FIND_ALL | HL_FIND_NO_RECURSE);
                }
            }

            printf("\n");

            // Could also have used hlFolderGetFolderCount() and
            // hlFolderGetFileCount().

            printf("Summary:\n");
            printf("\n");
            printf("  %u Folder%s.\n", uiFolderCount, uiFolderCount != 1 ? "s" : "");
            printf("  %u File%s.\n", uiFileCount, uiFileCount != 1 ? "s" : "");
            printf("\n");
        }
        //
        // Change directory.
        // Good example of CDirectoryFolder::GetParent() and item casting.
        //
        else if(stricmp(lpCommand, "cd") == 0)
        {
            if(*lpArgument == 0)
            {
                printf("No argument for command cd supplied.\n");
            }
            else
            {
                if(stricmp(lpArgument, ".") == 0)
                {

                }
                else if(stricmp(lpArgument, "..") == 0)
                {
                    if(hlItemGetParent(pItem) != 0)
                    {
                        pItem = hlItemGetParent(pItem);
                    }
                    else
                    {
                        printf("Folder does not have a parent.\n");
                    }
                }
                else
                {
                    bFound = hlFalse;
                    uiItemCount = hlFolderGetCount(pItem);
                    for(i = 0; i < uiItemCount; i++)
                    {
                        pSubItem = hlFolderGetItem(pItem, i);
                        if(hlItemGetType(pSubItem) == HL_ITEM_FOLDER && stricmp(lpArgument, hlItemGetName(pSubItem)) == 0)
                        {
                            bFound = hlTrue;
                            pItem = pSubItem;
                            break;
                        }
                    }

                    if(!bFound)
                    {
                        printf("%s not found.\n", lpArgument);
                    }
                }
            }
        }
        //
        // Go to the root folder.
        //
        else if(stricmp(lpCommand, "root") == 0)
        {
            pItem = hlPackageGetRoot();
        }
        //
        // Item information.
        // Good example of CPackageUtility helper functions.
        //
        else if(stricmp(lpCommand, "info") == 0)
        {
            if(*lpArgument == 0)
            {
                printf("No argument for command info supplied.\n");
            }
            else
            {
                pSubItem = hlFolderGetItemByPath(pItem, lpArgument, HL_FIND_ALL);

                if(pSubItem != 0)
                {
                    *lpTempBuffer = 0;
                    hlItemGetPath(pSubItem, lpTempBuffer, sizeof(lpTempBuffer));

                    printf("Information for %s:\n", lpTempBuffer);
                    printf("\n");

                    switch(hlItemGetType(pSubItem))
                    {
                    case HL_ITEM_FOLDER:
                        printf("  Type: Folder\n");
#ifdef _WIN32
                        printf("  Size: %I64u B\n", hlFolderGetSizeEx(pSubItem, hlTrue));
                        printf("  Size On Disk: %I64u B\n", hlFolderGetSizeOnDiskEx(pSubItem, hlTrue));
#else
                        printf("  Size: %llu B\n", hlFolderGetSizeEx(pSubItem, hlTrue));
                        printf("  Size On Disk: %llu B\n", hlFolderGetSizeOnDiskEx(pSubItem, hlTrue));
#endif
                        printf("  Folders: %u\n", hlFolderGetFolderCount(pSubItem, hlTrue));
                        printf("  Files: %u\n", hlFolderGetFileCount(pSubItem, hlTrue));
                        break;
                    case HL_ITEM_FILE:
                        printf("  Type: File\n");
                        printf("  Extractable: %s\n", hlFileGetExtractable(pSubItem) ? "True" : "False");
                        //printf("  Validates: %s\n", hlFileGetValidates(pSubItem) ? "True" : "False");
                        printf("  Size: %u B\n", hlFileGetSize(pSubItem));
                        printf("  Size On Disk: %u B\n", hlFileGetSizeOnDisk(pSubItem));
                        break;
                    }

                    uiItemCount = hlPackageGetItemAttributeCount();
                    for(i = 0; i < uiItemCount; i++)
                    {
                        if(hlPackageGetItemAttribute(pSubItem, i, &Attribute))
                        {
                            PrintAttribute("  ", &Attribute, "");
                        }
                    }

                    printf("\n");
                }
                else
                {
                    printf("%s not found.\n", lpArgument);
                }
            }
        }
        //
        // Extract item.
        // Good example of CPackageUtility extract functions.
        //
        else if(stricmp(lpCommand, "extract") == 0)
        {
            if(*lpArgument == 0)
            {
                printf("No argument for command extract supplied.\n");
            }
            else
            {
                if(stricmp(lpArgument, ".") == 0)
                {
                    pSubItem = pItem;
                }
                else
                {
                    pSubItem = hlFolderGetItemByName(pItem, lpArgument, HL_FIND_ALL);
                }

                if(pSubItem)
                {
                    // Extract the item.
                    // Item is extracted to cDestination\Item->GetName().
                    if(!bSilent)
                    {
                        printf("Extracting %s...\n", hlItemGetName(pSubItem));
                        printf("\n");
                    }

                    hlItemExtract(pSubItem, lpDestination);

                    if(!bSilent)
                    {
                        printf("\n");
                        printf("Done.\n");
                    }
                }
                else
                {
                    printf("%s not found.\n", lpArgument);
                }
            }
        }
        //
        // Validate item.
        // Validates the checksums of each item.
        //
        else if(stricmp(lpCommand, "validate") == 0)
        {
            if(*lpArgument == 0)
            {
                printf("No argument for command extract supplied.\n");
            }
            else
            {
                if(stricmp(lpArgument, ".") == 0)
                {
                    pSubItem = pItem;
                }
                else
                {
                    pSubItem = hlFolderGetItemByName(pItem, lpArgument, HL_FIND_ALL);
                }

                if(pSubItem)
                {
                    if(!bSilent)
                    {
                        printf("Validating %s...\n", hlItemGetName(pSubItem));
                        printf("\n");
                    }

                    Validate(pSubItem);

                    if(!bSilent)
                    {
                        printf("\n");
                        printf("Done.\n");
                    }
                }
                else
                {
                    printf("%s not found.\n", lpArgument);
                }
            }
        }
        //
        // Find items.
        // Good example of recursive directory navigation (Search() function).
        //
        else if(stricmp(lpCommand, "find") == 0)
        {
            if(*lpArgument == 0)
            {
                printf("No argument for command find supplied.\n");
            }
            else
            {
                // Search for the requested items.
                if(!bSilent)
                {
                    printf("Searching for %s...\n", lpArgument);
                    printf("\n");
                }

                uiItemCount = 0;
                pSubItem = hlFolderFindFirst(pItem, lpArgument, HL_FIND_ALL);
                while(pSubItem)
                {
                    hlItemGetPath(pSubItem, lpTempBuffer, sizeof(lpTempBuffer));

                    // Print the path.
                    uiItemCount++;
                    Print(hlItemGetType(pSubItem) == HL_ITEM_FILE ? FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY : GetColor(), "  Found %s: %s\n", hlItemGetType(pSubItem) == HL_ITEM_FOLDER ? "folder" : "file", lpTempBuffer);

                    pSubItem = hlFolderFindNext(pItem, pSubItem, lpArgument, HL_FIND_ALL);
                }

                if(!bSilent)
                {
                    if(uiItemCount != 0)
                    {
                        printf("\n");
                    }

                    printf("  %u item%s found.\n", uiItemCount, uiItemCount != 1 ? "s" : "");
                    printf("\n");
                }
            }
        }
        //
        // Type files.
        // Good example of reading files into memory.
        //
        else if(stricmp(lpCommand, "type") == 0)
        {
            if(*lpArgument == 0)
            {
                printf("No argument for command type supplied.\n");
            }
            else
            {
                pSubItem = hlFolderGetItemByName(pItem, lpArgument, HL_FIND_FILES);

                if(pSubItem)
                {
                    *lpTempBuffer = 0;
                    hlItemGetPath(pSubItem, lpTempBuffer, sizeof(lpTempBuffer));

                    if(!bSilent)
                    {
                        printf("Type for %s:\n", lpTempBuffer);
                        printf("\n");
                    }

                    if(hlFileCreateStream(pSubItem, &pStream))
                    {
                        if(hlStreamOpen(pStream, HL_MODE_READ))
                        {
                            uiColor = GetColor();
                            SetColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);

                            while(hlStreamReadChar(pStream, &iChar))
                            {
                                if((iChar >= ' ' && iChar <= '~') || iChar == '\n' || iChar == '\t')
                                {
                                    putc(iChar, stdout);
                                }
                            }

                            SetColor(uiColor);

                            hlStreamClose(pStream);
                        }
                        else
                        {
                            Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error typing %s:\n%s\n", hlItemGetName(pSubItem), hlGetString(HL_ERROR_SHORT_FORMATED));
                        }

                        hlFileReleaseStream(pSubItem, pStream);
                        pStream = 0;
                    }
                    else
                    {
                        Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error typing %s:\n%s\n", hlItemGetName(pSubItem), hlGetString(HL_ERROR_SHORT_FORMATED));
                    }

                    if(!bSilent)
                    {
                        printf("\n");
                        printf("Done.\n");
                    }
                }
                else
                {
                    printf("%s not found.\n", lpArgument);
                }
            }
        }
        //
        // Open item.
        // Good example of opening packages inside packages.
        //
        else if(stricmp(lpCommand, "open") == 0)
        {
            if(*lpArgument == 0)
            {
                printf("No argument for command open supplied.\n");
            }
            else
            {
                pSubItem = hlFolderGetItemByName(pItem, lpArgument, HL_FIND_FILES);

                if(pSubItem)
                {
                    if(hlFileCreateStream(pSubItem, &pStream))
                    {
                        if(hlStreamOpen(pStream, HL_MODE_READ))
                        {
                            ePackageType = hlGetPackageTypeFromStream(pStream);

                            if(hlCreatePackage(ePackageType, &uiSubPackage))
                            {
                                hlBindPackage(uiSubPackage);
                                if(hlPackageOpenStream(pStream, HL_MODE_READ))
                                {
                                    if(!bSilent)
                                        Print(FOREGROUND_GREEN | FOREGROUND_INTENSITY, "%s opened.\n", hlItemGetName(pSubItem));

                                    EnterConsole(uiSubPackage, uiConsoleCommands, lpConsoleCommands);

                                    hlPackageClose();

                                    if(!bSilent)
                                        Print(FOREGROUND_GREEN | FOREGROUND_INTENSITY, "%s closed.\n", hlItemGetName(pSubItem));
                                }
                                else
                                {
                                    Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error opening %s:\n%s\n", hlItemGetName(pSubItem), hlGetString(HL_ERROR_SHORT_FORMATED));
                                }

                                hlDeletePackage(uiSubPackage);

                                hlBindPackage(uiPackage);
                            }
                            else
                            {
                                Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error opening %s:\n%s\n", hlItemGetName(pSubItem), hlGetString(HL_ERROR_SHORT_FORMATED));
                            }

                            hlStreamClose(pStream);
                        }
                        else
                        {
                            Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error opening %s:\n%s\n", hlItemGetName(pSubItem), hlGetString(HL_ERROR_SHORT_FORMATED));
                        }

                        hlFileReleaseStream(pSubItem, pStream);
                        pStream = 0;
                    }
                    else
                    {
                        Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error opening %s:\n%s\n", hlItemGetName(pSubItem), hlGetString(HL_ERROR_SHORT_FORMATED));
                    }
                }
                else
                {
                    printf("%s not found.\n", lpArgument);
                }
            }
        }
        //
        // Clear screen.
        //
        else if(stricmp(lpCommand, "status") == 0)
        {
#ifdef _WIN32
            printf("Total size: %I64u B\n", hlGetUnsignedLongLong(HL_PACKAGE_SIZE));
#else
            printf("Total size: %llu B\n", hlGetUnsignedLongLong(HL_PACKAGE_SIZE));
#endif
            printf("Total mapping allocations: %u\n", hlGetUnsignedInteger(HL_PACKAGE_TOTAL_ALLOCATIONS));
#ifdef _WIN32
            printf("Total mapping memory allocated: %I64u B\n", hlGetUnsignedLongLong(HL_PACKAGE_TOTAL_MEMORY_ALLOCATED));
            printf("Total mapping memory used: %I64u B\n", hlGetUnsignedLongLong(HL_PACKAGE_TOTAL_MEMORY_USED));
#else
            printf("Total mapping memory allocated: %llu B\n", hlGetUnsignedLongLong(HL_PACKAGE_TOTAL_MEMORY_ALLOCATED));
            printf("Total mapping memory used: %llu B\n", hlGetUnsignedLongLong(HL_PACKAGE_TOTAL_MEMORY_USED));
#endif

            uiItemCount = hlPackageGetAttributeCount();
            for(i = 0; i < uiItemCount; i++)
            {
                if(hlPackageGetAttribute(i, &Attribute))
                {
                    PrintAttribute("", &Attribute, "");
                }
            }
        }
#ifdef _WIN32
        else if(stricmp(lpCommand, "cls") == 0)
        {
            system("cls");
        }
#endif
        else if(stricmp(lpCommand, "help") == 0)
        {
            printf("Valid commands:\n");
            printf("\n");
#ifdef _WIN32
            printf("dir <filter>    (Directory list.)\n");
#else
            printf("ls <filter>     (Directory list.)\n");
#endif
            printf("cd <folder>     (Change directroy.)\n");
            printf("info <item>     (Item information.)\n");
            printf("extract <item>  (Extract item.)\n");
            printf("validate <item> (Validate item.)\n");
            printf("find <filter>   (Find item.)\n");
            printf("type <file>     (Type a file.)\n");
            printf("open <file>     (Open a nested package.)\n");
            printf("root            (Go to the root folder.)\n");
            printf("status          (Package information.)\n");
#ifdef _WIN32
            printf("cls             (Clear the screen.)\n");
#endif
            printf("help            (Program help.)\n");
            printf("exit            (Quit program.)\n");
            printf("\n");
        }
        else if(stricmp(lpCommand, "exit") == 0)
        {
            break;
        }
        else
        {
            printf("Unkown command: %s\n", lpCommand);
        }
    }
}
예제 #6
0
파일: Main.c 프로젝트: Rupan/HLLib
int main(hlInt argc, hlChar* argv[])
{
    hlUInt i;

    // Arguments.
    hlUInt uiArgumentCount = (hlUInt)argc;
    hlChar *lpPackage = 0;
    hlUInt uiExtractItems = 0;
    hlChar *lpExtractItems[MAX_ITEMS];
    hlUInt uiValidateItems = 0;
    hlChar *lpValidateItems[MAX_ITEMS];
    hlChar *lpList = 0;
    hlBool bDefragment = hlFalse;
    hlChar *lpNCFRootPath = 0;

    hlBool bList = hlFalse;
    hlBool bListFolders = hlFalse;
    hlBool bListFiles = hlFalse;
    FILE *pFile = 0;

    hlBool bConsoleMode = hlFalse;
    hlUInt uiConsoleCommands = 0;
    hlChar *lpConsoleCommands[MAX_ITEMS];
    hlBool bFileMapping = hlFalse;
    hlBool bQuickFileMapping = hlFalse;
    hlBool bVolatileAccess = hlFalse;
    hlBool bOverwriteFiles = hlTrue;
    hlBool bForceDefragment = hlFalse;

    // Package stuff.
    HLPackageType ePackageType = HL_PACKAGE_NONE;
    hlUInt uiPackage = HL_ID_INVALID, uiMode = HL_MODE_INVALID;
    HLDirectoryItem *pItem = 0;

    if(hlGetUnsignedInteger(HL_VERSION) < HL_VERSION_NUMBER)
    {
        printf("Wrong HLLib version: v%s.\n", hlGetString(HL_VERSION));
        return 1;
    }

    // Process switches.
    if(uiArgumentCount == 2)
    {
        // The user just specified a file, drop into console mode.
        lpPackage = argv[1];
        bConsoleMode = hlTrue;
        bVolatileAccess = hlTrue;
    }
    else
    {
        for(i = 1; i < uiArgumentCount; i++)
        {
            if(stricmp(argv[i], "-p") == 0 || stricmp(argv[i], "--package") == 0)
            {
                if(lpPackage == 0 && i + 1 < uiArgumentCount)
                {
                    lpPackage = argv[++i];
                }
                else
                {
                    PrintUsage();
                    return 2;
                }
            }
            else if(stricmp(argv[i], "-d") == 0 || stricmp(argv[i], "--dest") == 0)
            {
                if(*lpDestination == 0 && i + 1 < uiArgumentCount)
                {
                    strcpy(lpDestination, argv[++i]);
                }
                else
                {
                    PrintUsage();
                    return 2;
                }
            }
            else if(stricmp(argv[i], "-e") == 0 || stricmp(argv[i], "--extract") == 0)
            {
                if(i + 1 < uiArgumentCount)
                {
                    if(uiExtractItems == MAX_ITEMS)
                    {
                        Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error loading package:\nMAX_ITEMS\n");
                        return 2;
                    }
                    lpExtractItems[uiExtractItems++] = argv[++i];
                }
                else
                {
                    PrintUsage();
                    return 2;
                }
            }
            else if(stricmp(argv[i], "-t") == 0 || stricmp(argv[i], "--validate") == 0)
            {
                if(i + 1 < uiArgumentCount)
                {
                    if(uiValidateItems == MAX_ITEMS)
                    {
                        Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error loading package:\nMAX_ITEMS\n");
                        return 2;
                    }
                    lpValidateItems[uiValidateItems++] = argv[++i];
                }
                else
                {
                    PrintUsage();
                    return 2;
                }
            }
            else if(strnicmp(argv[i], "-l", 2) == 0 || stricmp(argv[i], "--list") == 0)
            {
                if(bList)
                {
                    PrintUsage();
                    return 2;
                }

                bList = hlTrue;

                if(stricmp(argv[i], "-l") == 0 || stricmp(argv[i], "--list") == 0)
                {
                    // By default list everything.
                    bListFolders = hlTrue;
                    bListFiles = hlTrue;
                }
                else
                {
                    // List folders and files if specified.
                    bListFolders = strcspn(argv[i], "dD") != strlen(argv[i]);
                    bListFiles = strcspn(argv[i], "fF") != strlen(argv[i]);
                }

                // Check to see if we need to dump our list to a file.
                if(i + 1 < uiArgumentCount && *argv[i + 1] != '-')
                {
                    lpList = argv[++i];
                }
            }
            else if(stricmp(argv[i], "-f") == 0 || stricmp(argv[i], "--defragment") == 0)
            {
                bDefragment = hlTrue;
            }
            else if(stricmp(argv[i], "-n") == 0 || stricmp(argv[i], "--ncfroot") == 0)
            {
                if(lpNCFRootPath == 0 && i + 1 < uiArgumentCount)
                {
                    lpNCFRootPath = argv[++i];
                }
                else
                {
                    PrintUsage();
                    return 2;
                }
            }
            else if(stricmp(argv[i], "-s") == 0 || stricmp(argv[i], "--silent") == 0)
            {
                bSilent = hlTrue;
            }
            else if(stricmp(argv[i], "-c") == 0 || stricmp(argv[i], "--console") == 0)
            {
                bConsoleMode = hlTrue;
            }
            else if(stricmp(argv[i], "-x") == 0 || stricmp(argv[i], "--execute") == 0)
            {
                if(i + 1 < uiArgumentCount)
                {
                    if(uiConsoleCommands == MAX_ITEMS)
                    {
                        Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error loading package:\nMAX_ITEMS\n");
                        return 2;
                    }
                    lpConsoleCommands[uiConsoleCommands++] = argv[++i];
                }
                else
                {
                    PrintUsage();
                    return 2;
                }
            }
            else if(stricmp(argv[i], "-m") == 0 || stricmp(argv[i], "--filemapping") == 0)
            {
                bFileMapping = hlTrue;
            }
            else if(stricmp(argv[i], "-q") == 0 || stricmp(argv[i], "--quick-filemapping") == 0)
            {
                bFileMapping = hlTrue;
                bQuickFileMapping = hlTrue;
            }
            else if(stricmp(argv[i], "-v") == 0 || stricmp(argv[i], "--volatile") == 0)
            {
                bVolatileAccess = hlTrue;
            }
            else if(stricmp(argv[i], "-o") == 0 || stricmp(argv[i], "--overwrite") == 0)
            {
                bOverwriteFiles = hlFalse;
            }
            else if(stricmp(argv[i], "-r") == 0 || stricmp(argv[i], "--force-defragment") == 0)
            {
                bDefragment = hlTrue;
                bForceDefragment = hlTrue;
            }
            else
            {
                PrintUsage();
                return 2;
            }
        }
    }

    // Make sure we have something to do.
    if(lpPackage == 0 || (uiExtractItems == 0 && uiValidateItems == 0 && !bList && !bDefragment && !bConsoleMode))
    {
        PrintUsage();
        return 2;
    }

    // If the destination directory is not specified, make it the input directory.
    if(*lpDestination == 0)
    {
        const hlChar *pForward = strrchr(lpPackage, '\\');
        const hlChar *pBackward = strrchr(lpPackage, '/');
        const hlChar *pEnd = pForward > pBackward ? pForward : pBackward;
        if(pEnd != 0)
        {
            strncpy(lpDestination, lpPackage, pEnd - lpPackage);
            lpDestination[pEnd - lpPackage] = '\0';
        }
    }

    hlInitialize();

    hlSetBoolean(HL_OVERWRITE_FILES, bOverwriteFiles);
    hlSetBoolean(HL_FORCE_DEFRAGMENT, bForceDefragment);
    hlSetVoid(HL_PROC_EXTRACT_ITEM_START, ExtractItemStartCallback);
    hlSetVoid(HL_PROC_EXTRACT_ITEM_END, ExtractItemEndCallback);
    hlSetVoid(HL_PROC_EXTRACT_FILE_PROGRESS, FileProgressCallback);
    hlSetVoid(HL_PROC_VALIDATE_FILE_PROGRESS, FileProgressCallback);
    hlSetVoid(HL_PROC_DEFRAGMENT_PROGRESS_EX, DefragmentProgressCallback);

    // Get the package type from the filename extension.
    ePackageType = hlGetPackageTypeFromName(lpPackage);

    // If the above fails, try getting the package type from the data at the start of the file.
    if(ePackageType == HL_PACKAGE_NONE)
    {
        pFile = fopen(lpPackage, "rb");
        if(pFile != 0)
        {
            hlByte lpBuffer[HL_DEFAULT_PACKAGE_TEST_BUFFER_SIZE];

            hlUInt uiBufferSize = (hlUInt)fread(lpBuffer, 1, HL_DEFAULT_PACKAGE_TEST_BUFFER_SIZE, pFile);

            ePackageType = hlGetPackageTypeFromMemory(lpBuffer, uiBufferSize);

            fclose(pFile);
            pFile = 0;
        }
    }

    if(ePackageType == HL_PACKAGE_NONE)
    {
        Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error loading %s:\nUnsupported package type.\n", lpPackage);

        hlShutdown();
        return 3;
    }

    // Create a package element, the element is allocated by the library and cleaned
    // up by the library.  An ID is generated which must be bound to apply operations
    // to the package.
    if(!hlCreatePackage(ePackageType, &uiPackage))
    {
        Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error loading %s:\n%s\n", lpPackage, hlGetString(HL_ERROR_SHORT_FORMATED));

        hlShutdown();
        return 3;
    }

    hlBindPackage(uiPackage);

    uiMode = HL_MODE_READ | (bDefragment ? HL_MODE_WRITE : 0);
    uiMode |= !bFileMapping ? HL_MODE_NO_FILEMAPPING : 0;
    uiMode |= bQuickFileMapping ? HL_MODE_QUICK_FILEMAPPING : 0;
    uiMode |= bVolatileAccess ? HL_MODE_VOLATILE : 0;

    // Open the package.
    // Of the above modes, only HL_MODE_READ is required.  HL_MODE_WRITE is present
    // only for future use.  File mapping is recommended as an efficient way to load
    // packages.  Quick file mapping maps the entire file (instead of bits as they are
    // needed) and thus should only be used in Windows 2000 and up (older versions of
    // Windows have poor virtual memory management which means large files won't be able
    // to find a continues block and will fail to load).  Volatile access allows HLLib
    // to share files with other applications that have those file open for writing.
    // This is useful for, say, loading .gcf files while Steam is running.
    if(!hlPackageOpenFile(lpPackage, uiMode))
    {
        Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error loading %s:\n%s\n", lpPackage, hlGetString(HL_ERROR_SHORT_FORMATED));

        hlShutdown();
        return 3;
    }

    // If we have a .ncf file, the package file data is stored externally.  In order to
    // validate the file data etc., HLLib needs to know where to look.  Tell it where.
    if(ePackageType == HL_PACKAGE_NCF)
    {
        hlNCFFileSetRootPath(lpNCFRootPath);
    }

    if(!bSilent)
        Print(FOREGROUND_GREEN | FOREGROUND_INTENSITY, "%s opened.\n", lpPackage);

    // Extract the requested items.
    for(i = 0; i < uiExtractItems; i++)
    {
        // Find the item.
        pItem = hlFolderGetItemByPath(hlPackageGetRoot(), lpExtractItems[i], HL_FIND_ALL);

        if(pItem == 0)
        {
            printf("%s not found in package.\n", lpExtractItems[i]);
            continue;
        }

        if(!bSilent)
        {
            Print(FOREGROUND_GREEN | FOREGROUND_INTENSITY, "Extracting %s...\n", hlItemGetName(pItem));
            printf("\n");
        }

        // Extract the item.
        // Item is extracted to cDestination\Item->GetName().
        hlItemExtract(pItem, lpDestination);

        if(!bSilent)
        {
            printf("\n");
            printf("Done.\n");
        }
    }

    // Validate the requested items.
    for(i = 0; i < uiValidateItems; i++)
    {
        // Find the item.
        pItem = hlFolderGetItemByPath(hlPackageGetRoot(), lpValidateItems[i], HL_FIND_ALL);

        if(pItem == 0)
        {
            printf("%s not found in package.\n", lpValidateItems[i]);
            continue;
        }

        if(!bSilent)
        {
            Print(FOREGROUND_GREEN | FOREGROUND_INTENSITY, "Validating %s...\n", hlItemGetName(pItem));
            printf("\n");
        }

        // Validate the item.
        Validate(pItem);

        if(!bSilent)
        {
            printf("\n");
            printf("Done.\n");
        }
    }

    // List items in package.
    if(bList)
    {
        if(!bSilent)
        {
            printf("Listing...\n");
            printf("\n");
        }

        pFile = stdout;

        if(lpList != 0)
        {
            pFile = fopen(lpList, "wt");

            if(pFile == 0)
            {
                Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error opening %s:\n%s\n", lpList, "fopen() failed.");
                pFile = stdout;
            }
        }

        List(pFile, hlPackageGetRoot(), bListFolders, bListFiles);

        if(lpList != 0)
        {
            fclose(pFile);
            pFile = 0;
        }

        if(!bSilent)
        {
            printf("\n");
            printf("Done.\n");
        }
    }

    if(bDefragment)
    {
        if(!bSilent)
        {
            printf("Defragmenting...\n");
            printf("\n");

            ProgressStart();
            printf("  Progress: ");
        }

        if(!hlPackageDefragment())
        {
            Print(FOREGROUND_RED | FOREGROUND_INTENSITY, " %s", hlGetString(HL_ERROR_SHORT_FORMATED));
        }

        if(!bSilent)
        {
            printf("\n");

            printf("\n");
            printf("Done.\n");
        }
    }

    // Interactive console mode.
    // Commands: dir, cd, root, info, extract, find, type, cls, help, exit.
    if(bConsoleMode)
    {
        EnterConsole(uiPackage, uiConsoleCommands, lpConsoleCommands);
    }

    // Close the package.
    hlPackageClose();

    if(!bSilent)
        Print(FOREGROUND_GREEN | FOREGROUND_INTENSITY, "%s closed.\n", lpPackage);

    // Free up the allocated memory.
    hlDeletePackage(uiPackage);

    hlShutdown();

    return 0;
}