public static Stream CreateFileGroupDescriptorW(string fileName, DateTimeOffset lastWriteTime) { var fileGroupDescriptor = new FILEGROUPDESCRIPTORW() { cItems = 1 }; var fileDescriptor = new FILEDESCRIPTORW() { cFileName = fileName }; fileDescriptor.dwFlags |= FD_SHOWPROGRESSUI; fileDescriptor.dwFlags |= FD_CREATETIME | FD_WRITESTIME; var changeTime = lastWriteTime.ToLocalTime().ToFileTime(); var changeTimeFileTime = new System.Runtime.InteropServices.ComTypes.FILETIME { dwLowDateTime = (int)(changeTime & 0xffffffff), dwHighDateTime = (int)(changeTime >> 32), }; fileDescriptor.ftLastWriteTime = changeTimeFileTime; fileDescriptor.ftCreationTime = changeTimeFileTime; var fileGroupDescriptorBytes = StructureBytes(fileGroupDescriptor); var fileDescriptorBytes = StructureBytes(fileDescriptor); var memoryStream = new MemoryStream(); memoryStream.Write(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length); memoryStream.Write(fileDescriptorBytes, 0, fileDescriptorBytes.Length); return(memoryStream); }
public static Stream CreateFileGroupDescriptorW(string fileName, DateTimeOffset lastWriteTime, long?fileSize) { var fileGroupDescriptor = new FILEGROUPDESCRIPTORW() { cItems = 1 }; var fileDescriptor = new FILEDESCRIPTORW() { cFileName = fileName }; fileDescriptor.dwFlags |= FD_SHOWPROGRESSUI; if (lastWriteTime != default) { fileDescriptor.dwFlags |= FD_CREATETIME | FD_WRITESTIME; var changeTime = lastWriteTime.ToFileTime(); var changeTimeFileTime = new System.Runtime.InteropServices.ComTypes.FILETIME { dwLowDateTime = (int)(changeTime & 0xffffffff), dwHighDateTime = (int)(changeTime >> 32), }; fileDescriptor.ftLastWriteTime = changeTimeFileTime; fileDescriptor.ftCreationTime = changeTimeFileTime; } if (fileSize.HasValue) { fileDescriptor.dwFlags |= FD_FILESIZE; // TODO: remove ! once https://github.com/dotnet/roslyn/issues/33330 is fixed fileDescriptor.nFileSizeLow = (uint)(fileSize & 0xffffffff) !; fileDescriptor.nFileSizeHigh = (uint)(fileSize >> 32) !; } var fileGroupDescriptorBytes = StructureBytes(fileGroupDescriptor); var fileDescriptorBytes = StructureBytes(fileDescriptor); var memoryStream = new MemoryStream(); memoryStream.Write(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length); memoryStream.Write(fileDescriptorBytes, 0, fileDescriptorBytes.Length); return(memoryStream); }
/// <summary> /// Retrieves the data associated with the specified data format, using a Boolean to determine whether to convert the data to the format. /// </summary> /// <param name="format">The format of the data to retrieve. See <see cref="T:System.Windows.DataFormats"></see> for predefined formats.</param> /// <param name="autoConvert">true to convert the data to the specified format; otherwise, false.</param> /// <returns> /// The data associated with the specified format, or null. /// </returns> public object GetData(string format, bool autoConvert) { //handle the "FileGroupDescriptor" and "FileContents" format request in this class otherwise pass through to underlying IDataObject switch (format) { case "FileGroupDescriptor": //override the default handling of FileGroupDescriptor which returns a //MemoryStream and instead return a string array of file names IntPtr fileGroupDescriptorAPointer = IntPtr.Zero; try { //use the underlying IDataObject to get the FileGroupDescriptor as a MemoryStream MemoryStream fileGroupDescriptorStream = (MemoryStream)this._underlyingDataObject.GetData("FileGroupDescriptor", autoConvert); byte[] fileGroupDescriptorBytes = new byte[fileGroupDescriptorStream.Length]; fileGroupDescriptorStream.Read(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length); fileGroupDescriptorStream.Close(); //copy the file group descriptor into unmanaged memory fileGroupDescriptorAPointer = Marshal.AllocHGlobal(fileGroupDescriptorBytes.Length); Marshal.Copy(fileGroupDescriptorBytes, 0, fileGroupDescriptorAPointer, fileGroupDescriptorBytes.Length); //marshal the unmanaged memory to to FILEGROUPDESCRIPTORA struct object fileGroupDescriptorObject = Marshal.PtrToStructure(fileGroupDescriptorAPointer, typeof(FILEGROUPDESCRIPTORA)); FILEGROUPDESCRIPTORA fileGroupDescriptor = (FILEGROUPDESCRIPTORA)fileGroupDescriptorObject; //create a new array to store file names in of the number of items in the file group descriptor string[] fileNames = new string[fileGroupDescriptor.cItems]; //get the pointer to the first file descriptor IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptorAPointer)); //loop for the number of files acording to the file group descriptor for (int fileDescriptorIndex = 0; fileDescriptorIndex < fileGroupDescriptor.cItems; fileDescriptorIndex++) { //marshal the pointer top the file descriptor as a FILEDESCRIPTORA struct and get the file name FILEDESCRIPTORA fileDescriptor = (FILEDESCRIPTORA)Marshal.PtrToStructure(fileDescriptorPointer, typeof(FILEDESCRIPTORA)); fileNames[fileDescriptorIndex] = fileDescriptor.cFileName; //move the file descriptor pointer to the next file descriptor fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor)); } //return the array of filenames return(fileNames); } finally { //free unmanaged memory pointer Marshal.FreeHGlobal(fileGroupDescriptorAPointer); } case "FileGroupDescriptorW": //override the default handling of FileGroupDescriptorW which returns a //MemoryStream and instead return a string array of file names IntPtr fileGroupDescriptorWPointer = IntPtr.Zero; try { //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream MemoryStream fileGroupDescriptorStream = (MemoryStream)this._underlyingDataObject.GetData("FileGroupDescriptorW"); byte[] fileGroupDescriptorBytes = new byte[fileGroupDescriptorStream.Length]; fileGroupDescriptorStream.Read(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length); fileGroupDescriptorStream.Close(); //copy the file group descriptor into unmanaged memory fileGroupDescriptorWPointer = Marshal.AllocHGlobal(fileGroupDescriptorBytes.Length); Marshal.Copy(fileGroupDescriptorBytes, 0, fileGroupDescriptorWPointer, fileGroupDescriptorBytes.Length); //marshal the unmanaged memory to to FILEGROUPDESCRIPTORW struct object fileGroupDescriptorObject = Marshal.PtrToStructure(fileGroupDescriptorWPointer, typeof(FILEGROUPDESCRIPTORW)); FILEGROUPDESCRIPTORW fileGroupDescriptor = (FILEGROUPDESCRIPTORW)fileGroupDescriptorObject; //create a new array to store file names in of the number of items in the file group descriptor string[] fileNames = new string[fileGroupDescriptor.cItems]; //get the pointer to the first file descriptor IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptorWPointer)); //loop for the number of files acording to the file group descriptor for (int fileDescriptorIndex = 0; fileDescriptorIndex < fileGroupDescriptor.cItems; fileDescriptorIndex++) { //marshal the pointer top the file descriptor as a FILEDESCRIPTORW struct and get the file name FILEDESCRIPTORW fileDescriptor = (FILEDESCRIPTORW)Marshal.PtrToStructure(fileDescriptorPointer, typeof(FILEDESCRIPTORW)); fileNames[fileDescriptorIndex] = fileDescriptor.cFileName; //move the file descriptor pointer to the next file descriptor fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor)); } //return the array of filenames return(fileNames); } finally { //free unmanaged memory pointer Marshal.FreeHGlobal(fileGroupDescriptorWPointer); } case "FileContents": //override the default handling of FileContents which returns the //contents of the first file as a memory stream and instead return //a array of MemoryStreams containing the data to each file dropped //get the array of filenames which lets us know how many file contents exist string[] fileContentNames = (string[])this.GetData("FileGroupDescriptor"); //create a MemoryStream array to store the file contents MemoryStream[] fileContents = new MemoryStream[fileContentNames.Length]; //loop for the number of files acording to the file names for (int fileIndex = 0; fileIndex < fileContentNames.Length; fileIndex++) { //get the data at the file index and store in array fileContents[fileIndex] = this.GetData(format, fileIndex); } //return array of MemoryStreams containing file contents return(fileContents); } //use underlying IDataObject to handle getting of data return(this._underlyingDataObject.GetData(format, autoConvert)); }