예제 #1
0
        internal static IntPtr FdiOpen(string filename, int oflag, int pmode)
        {
            FileMode mode = CabinetNativeApi.ConvertOpflagToFileMode(oflag);

            FileAccess access = CabinetNativeApi.ConvertPermissionModeToFileAccess(pmode);
            FileShare  share  = CabinetNativeApi.ConvertPermissionModeToFileShare(pmode);

            // This method is used for opening the cab file as well as saving the extracted files.
            // When we are opening the cab file we only need read permissions.
            // We force read permissions so that non-elevated users can extract cab files.
            if (mode == FileMode.Open || mode == FileMode.OpenOrCreate)
            {
                access = FileAccess.Read;
                share  = FileShare.Read;
            }

            try
            {
                FileStream stream = new FileStream(filename, mode, access, share);

                if (stream == null)
                {
                    return(new IntPtr(-1));
                }

                return(GCHandle.ToIntPtr(GCHandle.Alloc(stream)));
            }
            catch (IOException)
            {
                return(new IntPtr(-1));
            }
        }
예제 #2
0
        internal override bool Extract(string cabinetName, string srcPath, string destPath)
        {
            IntPtr nativeDestPath = Marshal.StringToHGlobalAnsi(destPath);

            bool result = CabinetNativeApi.FDICopy(
                fdiContext,
                cabinetName,
                srcPath,
                0,                    // Not used
                Marshal.GetFunctionPointerForDelegate(_notifyDelegate),
                IntPtr.Zero,
                nativeDestPath);

            Marshal.FreeHGlobal(nativeDestPath);

            return(result);
        }
예제 #3
0
        internal CabinetNativeApi.FdiContextHandle fdiContext; // HFDI

        internal CabinetExtractor()
        {
            CabinetNativeApi.FdiERF err = new CabinetNativeApi.FdiERF();

            populateDelegates();

            // marshal the delegate to a unmanaged function pointer so that AppDomain reference is stored correctly.
            fdiContext = CabinetNativeApi.FDICreate(
                Marshal.GetFunctionPointerForDelegate(_allocDelegate),
                Marshal.GetFunctionPointerForDelegate(_freeDelegate),
                Marshal.GetFunctionPointerForDelegate(_openDelegate),
                Marshal.GetFunctionPointerForDelegate(_readDelegate),
                Marshal.GetFunctionPointerForDelegate(_writeDelegate),
                Marshal.GetFunctionPointerForDelegate(_closeDelegate),
                Marshal.GetFunctionPointerForDelegate(_seekDelegate),
                CabinetNativeApi.FdiCreateCpuType.Cpu80386,
                err);
        }
예제 #4
0
        internal static int FdiSeek(IntPtr fp, int offset, int origin)
        {
            GCHandle   handle = GCHandle.FromIntPtr(fp);
            FileStream stream = (FileStream)handle.Target;

            SeekOrigin seekOrigin = CabinetNativeApi.ConvertOriginToSeekOrigin(origin);
            long       status     = 0;

            try
            {
                status = stream.Seek(offset, seekOrigin);
            }
            catch (NotSupportedException) { status = -1; }
            catch (IOException) { status = -1; }
            catch (ArgumentException) { status = -1; }
            catch (ObjectDisposedException) { status = -1; }

            return((int)status);
        }
예제 #5
0
 protected override bool ReleaseHandle()
 {
     return(CabinetNativeApi.FDIDestroy(this.handle));
 }
예제 #6
0
        // Handles FDI notification
        internal static IntPtr FdiNotify(FdiNotificationType fdint, FdiNotification fdin)
        {
            switch (fdint)
            {
            case FdiNotificationType.FdintCOPY_FILE:
            {
                // TODO: Should I catch exceptions for the new functions?

                // Copy target directory
                string destPath = Marshal.PtrToStringAnsi(fdin.pv);

                // Split the path to a filename and path
                string fileName          = Path.GetFileName(fdin.psz1);
                string remainingPsz1Path = Path.GetDirectoryName(fdin.psz1);
                destPath = Path.Combine(destPath, remainingPsz1Path);

                Directory.CreateDirectory(destPath);         // Creates all intermediate directories if necessary.

                // Create the file
                string absoluteFilePath = Path.Combine(destPath, fileName);
                return(CabinetNativeApi.FdiOpen(absoluteFilePath, (int)OpFlags.Create, (int)(PermissionMode.Read | PermissionMode.Write)));        // TODO: OK to ignore _O_SEQUENTIAL, WrOnly, and _O_BINARY?
            }

            case FdiNotificationType.FdintCLOSE_FILE_INFO:
            {
                // Close the file
                CabinetNativeApi.FdiClose(fdin.hf);

                // Set the file attributes
                string destPath         = Marshal.PtrToStringAnsi(fdin.pv);
                string absoluteFilePath = Path.Combine(destPath, fdin.psz1);

                IntPtr hFile = PlatformInvokes.CreateFile(
                    absoluteFilePath,
                    PlatformInvokes.FileDesiredAccess.GenericRead | PlatformInvokes.FileDesiredAccess.GenericWrite,
                    PlatformInvokes.FileShareMode.Read,
                    IntPtr.Zero,
                    PlatformInvokes.FileCreationDisposition.OpenExisting,
                    PlatformInvokes.FileAttributes.Normal,
                    IntPtr.Zero);

                if (hFile != IntPtr.Zero)
                {
                    PlatformInvokes.FILETIME ftFile = new PlatformInvokes.FILETIME();
                    if (PlatformInvokes.DosDateTimeToFileTime(fdin.date, fdin.time, ftFile))
                    {
                        PlatformInvokes.FILETIME ftLocal = new PlatformInvokes.FILETIME();
                        if (PlatformInvokes.LocalFileTimeToFileTime(ftFile, ftLocal))
                        {
                            PlatformInvokes.SetFileTime(hFile, ftLocal, null, ftLocal);
                        }
                    }

                    PlatformInvokes.CloseHandle(hFile);
                }

                PlatformInvokes.SetFileAttributesW(
                    absoluteFilePath,
                    (PlatformInvokes.FileAttributes)fdin.attribs & (PlatformInvokes.FileAttributes.ReadOnly | PlatformInvokes.FileAttributes.Hidden | PlatformInvokes.FileAttributes.System | PlatformInvokes.FileAttributes.Archive));

                // Call notification function
                return(new IntPtr(1));
            }
            }

            return(new IntPtr(0));
        }