aboutsummaryrefslogtreecommitdiff
path: root/mounter.c
diff options
context:
space:
mode:
Diffstat (limited to 'mounter.c')
-rw-r--r--mounter.c350
1 files changed, 350 insertions, 0 deletions
diff --git a/mounter.c b/mounter.c
new file mode 100644
index 0000000..256b7c4
--- /dev/null
+++ b/mounter.c
@@ -0,0 +1,350 @@
+/*
+ HTTP virtual disk driver for Windows.
+ Copyright (C) 1999-2009 Bo Brantén.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <winioctl.h>
+#include <winsock2.h>
+#include <shlobj.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "httpdisk.h"
+#include "mounter.h"
+
+static void PrintLastError(const char* Prefix)
+{
+ LPVOID lpMsgBuf;
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ 0,
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ MessageBox(NULL, lpMsgBuf, Prefix, MB_ICONEXCLAMATION | MB_OK);
+ //fprintf(stderr, "%s: %s", Prefix, (LPTSTR) lpMsgBuf);
+
+ LocalFree(lpMsgBuf);
+}
+
+int
+HttpDiskMount(
+ int DeviceNumber,
+ PHTTP_DISK_INFORMATION HttpDiskInformation,
+ BOOLEAN CdImage
+)
+{
+ char VolumeName[] = "\\\\.\\ :";
+ char DriveName[] = " :\\";
+ char DeviceName[255];
+ HANDLE Device;
+ DWORD BytesReturned;
+
+ VolumeName[4] = HttpDiskInformation->DriveLetter;
+ DriveName[0] = HttpDiskInformation->DriveLetter;
+
+ Device = CreateFile(
+ VolumeName,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_NO_BUFFERING,
+ NULL
+ );
+
+ if (Device != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(Device);
+ SetLastError(ERROR_BUSY);
+ PrintLastError(&VolumeName[4]);
+ return -1;
+ }
+
+ if (CdImage)
+ {
+ sprintf(DeviceName, DEVICE_NAME_PREFIX "Cd" "%u", DeviceNumber);
+ }
+ else
+ {
+ sprintf(DeviceName, DEVICE_NAME_PREFIX "Disk" "%u", DeviceNumber);
+ }
+
+ if (!DefineDosDevice(
+ DDD_RAW_TARGET_PATH,
+ &VolumeName[4],
+ DeviceName
+ ))
+ {
+ PrintLastError(&VolumeName[4]);
+ return -1;
+ }
+
+ Device = CreateFile(
+ VolumeName,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_NO_BUFFERING,
+ NULL
+ );
+
+ if (Device == INVALID_HANDLE_VALUE)
+ {
+ PrintLastError(&VolumeName[4]);
+ DefineDosDevice(DDD_REMOVE_DEFINITION, &VolumeName[4], NULL);
+ return -1;
+ }
+
+ if (!DeviceIoControl(
+ Device,
+ IOCTL_HTTP_DISK_CONNECT,
+ HttpDiskInformation,
+ sizeof(HTTP_DISK_INFORMATION) + HttpDiskInformation->FileNameLength - 1,
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL
+ ))
+ {
+ PrintLastError("HttpDisk");
+ DefineDosDevice(DDD_REMOVE_DEFINITION, &VolumeName[4], NULL);
+ CloseHandle(Device);
+ return -1;
+ }
+
+ CloseHandle(Device);
+
+ SHChangeNotify(SHCNE_DRIVEADD, SHCNF_PATH, DriveName, NULL);
+
+ return 0;
+}
+
+int
+HttpDiskMountUrl(
+ int DeviceNumber,
+ const char * Url,
+ char DriveLetter,
+ BOOLEAN CdImage
+)
+{
+ PHTTP_DISK_INFORMATION HttpDiskInformation;
+ char* FileName;
+ char* PortStr;
+ struct hostent* HostEnt;
+ WSADATA wsaData;
+
+ HttpDiskInformation = (PHTTP_DISK_INFORMATION) malloc(sizeof(HTTP_DISK_INFORMATION) + strlen(Url));
+
+ memset(
+ HttpDiskInformation,
+ 0,
+ sizeof(HTTP_DISK_INFORMATION) + strlen(Url)
+ );
+
+ if (strstr(Url, "//"))
+ {
+ if (strlen(Url) > 7 && !strncmp(Url, "http://", 7))
+ {
+ Url += 7;
+ }
+ else
+ {
+ fprintf(stderr, "Invalid protocol.\n");
+ return -1;
+ }
+ }
+
+ FileName = strstr(Url, "/");
+
+ if (!FileName)
+ {
+ fprintf(stderr, "%s: Invalid url.\n", Url);
+ return -1;
+ }
+
+ strcpy(HttpDiskInformation->FileName, FileName);
+
+ HttpDiskInformation->FileNameLength = (USHORT) strlen(HttpDiskInformation->FileName);
+
+ *FileName = '\0';
+
+ PortStr = strstr(Url, ":");
+
+ if (PortStr)
+ {
+ HttpDiskInformation->Port = htons((USHORT) atoi(PortStr + 1));
+
+ if (HttpDiskInformation->Port == 0)
+ {
+ fprintf(stderr, "%s: Invalid port.\n", PortStr + 1);
+ return -1;
+ }
+
+ *PortStr = '\0';
+ }
+ else
+ {
+ HttpDiskInformation->Port = htons(80);
+ }
+
+ HttpDiskInformation->HostNameLength = (USHORT) strlen(Url);
+
+ if (HttpDiskInformation->HostNameLength > 255)
+ {
+ fprintf(stderr, "%s: Host name to long.\n", Url);
+ return -1;
+ }
+
+ strcpy(HttpDiskInformation->HostName, Url);
+
+ HttpDiskInformation->Address = inet_addr(Url);
+
+ if (HttpDiskInformation->Address == INADDR_NONE)
+ {
+ if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
+ {
+ PrintLastError("HttpDisk");
+ return -1;
+ }
+
+ HostEnt = gethostbyname(Url);
+
+ if (!HostEnt)
+ {
+ PrintLastError(Url);
+ return -1;
+ }
+
+ HttpDiskInformation->Address = ((struct in_addr*) HostEnt->h_addr)->s_addr;
+ }
+
+ HttpDiskInformation->DriveLetter = DriveLetter;
+ return HttpDiskMount(DeviceNumber, HttpDiskInformation, CdImage);
+}
+
+int HttpDiskUmount(char DriveLetter)
+{
+ char VolumeName[] = "\\\\.\\ :";
+ char DriveName[] = " :\\";
+ HANDLE Device;
+ DWORD BytesReturned;
+
+ VolumeName[4] = DriveLetter;
+ DriveName[0] = DriveLetter;
+
+ Device = CreateFile(
+ VolumeName,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_NO_BUFFERING,
+ NULL
+ );
+
+ if (Device == INVALID_HANDLE_VALUE)
+ {
+ PrintLastError(&VolumeName[4]);
+ return -1;
+ }
+
+ if (!DeviceIoControl(
+ Device,
+ FSCTL_LOCK_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL
+ ))
+ {
+ PrintLastError(&VolumeName[4]);
+ CloseHandle(Device);
+ return -1;
+ }
+
+ if (!DeviceIoControl(
+ Device,
+ IOCTL_HTTP_DISK_DISCONNECT,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL
+ ))
+ {
+ PrintLastError("HttpDisk");
+ CloseHandle(Device);
+ return -1;
+ }
+
+ if (!DeviceIoControl(
+ Device,
+ FSCTL_DISMOUNT_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL
+ ))
+ {
+ PrintLastError(&VolumeName[4]);
+ CloseHandle(Device);
+ return -1;
+ }
+
+ if (!DeviceIoControl(
+ Device,
+ FSCTL_UNLOCK_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL
+ ))
+ {
+ PrintLastError(&VolumeName[4]);
+ CloseHandle(Device);
+ return -1;
+ }
+
+ CloseHandle(Device);
+
+ if (!DefineDosDevice(
+ DDD_REMOVE_DEFINITION,
+ &VolumeName[4],
+ NULL
+ ))
+ {
+ PrintLastError(&VolumeName[4]);
+ return -1;
+ }
+
+ SHChangeNotify(SHCNE_DRIVEREMOVED, SHCNF_PATH, DriveName, NULL);
+
+ return 0;
+} \ No newline at end of file