r30: Winnbd code from Folkert van Heusden <folkert@vanheusden.com>
authorpavel <pavel>
Sun, 13 Jul 2003 21:23:55 +0000 (21:23 +0000)
committerpavel <pavel>
Sun, 13 Jul 2003 21:23:55 +0000 (21:23 +0000)
winnbd/license.txt [new file with mode: 0644]
winnbd/nbdsrvr.cpp [new file with mode: 0644]
winnbd/nbdsrvr.dsp [new file with mode: 0644]
winnbd/nbdsrvr.dsw [new file with mode: 0644]
winnbd/readme.txt [new file with mode: 0644]

diff --git a/winnbd/license.txt b/winnbd/license.txt
new file mode 100644 (file)
index 0000000..046f4c6
--- /dev/null
@@ -0,0 +1,2 @@
+The license of this program can be obtained from: http://www.vanheusden.com/license.txt
+It is actually the GNU Public License.
diff --git a/winnbd/nbdsrvr.cpp b/winnbd/nbdsrvr.cpp
new file mode 100644 (file)
index 0000000..fc38e70
--- /dev/null
@@ -0,0 +1,359 @@
+#include <windows.h>
+#include <stdio.h>
+
+int portnr;
+char *filename;
+
+int READ(SOCKET sh, UCHAR *whereto, int howmuch)
+{
+       int pnt = 0;
+
+#ifdef _DEBUG
+       printf("read: %d bytes requested\n", howmuch);
+#endif
+
+       while(howmuch > 0)
+       {
+               int nread = recv(sh, (char *)&whereto[pnt], howmuch, 0);
+               if (nread == 0)
+                       break;
+               if (nread == SOCKET_ERROR)
+               {
+                       fprintf(stderr, "Connection dropped. Error: %d\n", WSAGetLastError());
+                       break;
+               }
+
+               pnt += nread;
+               howmuch -= nread;
+       }
+
+       return pnt;
+}
+
+int WRITE(SOCKET sh, UCHAR *wherefrom, int howmuch)
+{
+       int pnt = 0;
+
+       while(howmuch > 0)
+       {
+               int nwritten = send(sh, (char *)&wherefrom[pnt], howmuch, 0);
+               if (nwritten == 0)
+                       break;
+               if (nwritten == SOCKET_ERROR)
+               {
+                       fprintf(stderr, "Connection dropped. Error: %d\n", WSAGetLastError());
+                       break;
+               }
+
+               pnt += nwritten;
+               howmuch -= nwritten;
+       }
+
+       return pnt;
+}
+
+BOOL getu32(SOCKET sh, ULONG *val)
+{
+       UCHAR buffer[4];
+
+       if (READ(sh, buffer, 4) != 4)
+               return FALSE;
+
+       *val = (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + (buffer[3]);
+
+       return TRUE;
+}
+
+BOOL putu32(SOCKET sh, ULONG value)
+{
+       UCHAR buffer[4];
+
+       buffer[0] = (value >> 24) & 255;
+       buffer[1] = (value >> 16) & 255;
+       buffer[2] = (value >>  8) & 255;
+       buffer[3] = (value      ) & 255;
+
+       if (WRITE(sh, buffer, 4) != 4)
+               return FALSE;
+       else
+               return TRUE;
+}
+
+DWORD WINAPI draad(LPVOID data)
+{
+       SOCKET sockh = (SOCKET)data;
+       HANDLE fh;
+       char neg = 1;
+
+       // open file 'filename'
+       fh = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+       if (fh == INVALID_HANDLE_VALUE)
+       {
+               fprintf(stderr, "Error opening file %s: %d\n", filename, GetLastError());
+       }
+
+       for(;fh != INVALID_HANDLE_VALUE;)
+       {
+               UCHAR handle[9];
+               ULONG magic, from, len, type, dummy;
+
+               /* negotiating time? */
+               if (neg)
+               {
+                               printf("Negotiating...\n");
+                               if (WRITE(sockh, (unsigned char *)"NBDMAGIC", 8) != 8)
+                               {
+                                       fprintf(stderr, "Failed to send magic string\n");
+                                       break;
+                               }
+
+                               // some other magic value
+                               unsigned char magic[8];
+                               magic[0] = 0x00;
+                               magic[1] = 0x00;
+                               magic[2] = 0x42;
+                               magic[3] = 0x02;
+                               magic[4] = 0x81;
+                               magic[5] = 0x86;
+                               magic[6] = 0x12;
+                               magic[7] = 0x53;
+                               if (WRITE(sockh, magic, 8) != 8)
+                               {
+                                       fprintf(stderr, "Failed to send 2nd magic string\n");
+                                       break;
+                               }
+
+                               // send size of file
+                               unsigned char exportsize[8];
+                               DWORD fsize = GetFileSize(fh, NULL);
+                               if (fsize == 0xFFFFFFFF)
+                               {
+                                       fprintf(stderr, "Failed to get filesize. Error: %d\n", GetLastError());
+                                       break;
+                               }
+                               exportsize[7] = (fsize      ) & 255;
+                               exportsize[6] = (fsize >>  8) & 255;
+                               exportsize[5] = (fsize >> 16) & 255;
+                               exportsize[4] = (fsize >> 24) & 255;
+                               exportsize[3] = (fsize >> 32) & 255;
+                               exportsize[2] = (fsize >> 40) & 255;
+                               exportsize[1] = (fsize >> 48) & 255;
+                               exportsize[0] = (fsize >> 56) & 255;
+#ifdef _DEBUG
+                               printf("File is %ld bytes\n", fsize);
+#endif
+                               if (WRITE(sockh, exportsize, 8) != 8)
+                               {
+                                       fprintf(stderr, "Failed to send filesize\n");
+                                       break;
+                               }
+                               
+                               // send a couple of zeros */
+                               unsigned char buffer[128];
+                               memset(buffer, 0x00, 128);
+                               if (WRITE(sockh, buffer, 128) != 128)
+                               {
+                                       fprintf(stderr, "Failed to send a couple of 0x00s\n");
+                                       break;
+                               }
+
+                               printf("Started!\n");
+                               neg = 0;
+               }
+
+               if (getu32(sockh, &magic) == FALSE ||   // 0x12560953
+                       getu32(sockh, &type)  == FALSE ||       // 0=read,1=write
+                       READ(sockh, handle, 8) != 8    ||       // handle
+                       getu32(sockh, &dummy) == FALSE ||       // ... high word of offset
+                       getu32(sockh, &from)  == FALSE ||       // offset
+                       getu32(sockh, &len)   == FALSE)         // length
+               {
+                       fprintf(stderr, "Failed to read from socket\n");
+                       break;
+               }
+
+#ifdef _DEBUG
+               handle[8] = 0x00;
+               printf("Magic:    %lx\n", magic);
+               printf("Offset:   %ld\n", from);
+               printf("Len:      %ld\n", len);
+               printf("Handle:   %s\n", handle);
+               printf("Req.type: %ld (%s)\n\n", type, type?"write":"read");
+#endif
+
+               // verify protocol
+               if (magic != 0x25609513)
+               {
+                       fprintf(stderr, "Unexpected protocol version! (got: %lx, expected: 0x25609513)\n", magic);
+                       break;
+               }
+
+               // seek to 'from'
+               if (SetFilePointer(fh, from, NULL, FILE_BEGIN) == 0xFFFFFFFF)
+               {
+                       fprintf(stderr, "Error seeking in file %s to position %d: %d\n", filename, from, GetLastError());
+                       break;
+               }
+
+               if (type == 1)  // write
+               {
+                       while(len > 0)
+                       {
+                               DWORD dummy;
+                               UCHAR buffer[32768];
+                               // read from socket
+                               int nb = recv(sockh, (char *)buffer, min(len, 32768), 0);
+                               if (nb == 0)
+                                       break;
+
+                               // write to file;
+                               if (WriteFile(fh, buffer, nb, &dummy, NULL) == 0)
+                               {
+                                       fprintf(stderr, "Failed to write to %s: %d\n", filename, GetLastError());
+                                       break;
+                               }
+                               if (dummy != nb)
+                               {
+                                       fprintf(stderr, "Failed to write to %s: %d (written: %d, requested to write: %d)\n", filename, GetLastError(), dummy, nb);
+                                       break;
+                               }
+
+                               len -= nb;
+                       }
+                       if (len)        // connection was closed
+                       {
+                               fprintf(stderr, "Connection was dropped while receiving data\n");
+                               break;
+                       }
+
+                       // send 'ack'
+                       if (putu32(sockh, 0x67446698) == FALSE ||
+                               putu32(sockh, 0) == FALSE ||
+                               WRITE(sockh, handle, 8) != 8)
+                       {
+                               fprintf(stderr, "Failed to send through socket\n");
+                               break;
+                       }
+               }
+               else if (type == 0)
+               {
+                       // send 'ack'
+                       if (putu32(sockh, 0x67446698) == FALSE ||
+                               putu32(sockh, 0) == FALSE ||
+                               WRITE(sockh, handle, 8) != 8)
+                       {
+                               fprintf(stderr, "Failed to send through socket\n");
+                               break;
+                       }
+
+                       while(len > 0)
+                       {
+                               DWORD dummy;
+                               UCHAR buffer[32768];
+                               int nb = min(len, 32768);
+                               int pnt = 0;
+
+                               // read nb to buffer;
+                               if (ReadFile(fh, buffer, nb, &dummy, NULL) == 0)
+                               {
+                                       fprintf(stderr, "Failed to read from %s: %d\n", filename, GetLastError());
+                                       break;
+                               }
+                               if (dummy != nb)
+                               {
+                                       fprintf(stderr, "Failed to read from %s: %d\n", filename, GetLastError());
+                                       break;
+                               }
+
+                               // send through socket
+                               if (WRITE(sockh, buffer, nb) != nb) // connection was closed
+                               {
+                                       fprintf(stderr, "Connection dropped while sending block\n");
+                                       break;
+                               }
+
+                               len -= nb;
+                       }
+                       if (len)        // connection was closed
+                               break;
+               }
+               else
+               {
+                       printf("Unexpected commandtype: %d\n", type);
+                       break;
+               }
+       }
+
+       // close file
+       if (CloseHandle(fh) == 0)
+       {
+               fprintf(stderr, "Failed to close handle: %d\n", GetLastError());
+       }
+
+       closesocket(sockh);
+
+       ExitThread(0);
+
+       return 0;
+}
+       
+int main(int argc, char *argv[])
+{
+       SOCKET newconnh;
+       WSADATA WSAData;
+
+       printf("nbdsrvr v0.1, (C) 2003 by folkert@vanheusden.com\n");
+
+       if (argc != 3)
+       {
+               fprintf(stderr, "Usage: %s file portnr\n", argv[0]);
+               return 1;
+       }
+       filename = argv[1];
+       portnr = atoi(argv[2]);
+
+       // initialize WinSock library
+       (void)WSAStartup(0x101, &WSAData); 
+       
+       // create listener socket
+       newconnh= socket(AF_INET, SOCK_STREAM, 0);
+       if (newconnh == INVALID_SOCKET)
+               return -1;
+
+       // bind
+       struct sockaddr_in      ServerAddr;
+       int     ServerAddrLen;
+       ServerAddrLen = sizeof(ServerAddr);
+       memset((char *)&ServerAddr, '\0', ServerAddrLen);
+       ServerAddr.sin_family = AF_INET;
+       ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       ServerAddr.sin_port = htons(portnr);
+       if (bind(newconnh, (struct sockaddr *)&ServerAddr, ServerAddrLen) == -1)
+               return -1;
+
+       // listen
+       if (listen(newconnh, 5) == -1)
+               return -1;
+
+       for(;;)
+       {
+               SOCKET clienth;
+               struct sockaddr_in      clientaddr;
+               int     clientaddrlen;
+
+               clientaddrlen = sizeof(clientaddr);
+
+               /* accept a connection */
+               clienth = accept(newconnh, (struct sockaddr *)&clientaddr, &clientaddrlen);
+
+               if (clienth != INVALID_SOCKET)
+               {
+                       printf("Connection made with %s\n", inet_ntoa(clientaddr.sin_addr));
+
+                       DWORD tid;
+                       HANDLE th = CreateThread(NULL, 0, draad, (void *)clienth, 0, &tid);
+               }
+       }
+
+       return 0;
+}
diff --git a/winnbd/nbdsrvr.dsp b/winnbd/nbdsrvr.dsp
new file mode 100644 (file)
index 0000000..9909542
--- /dev/null
@@ -0,0 +1,90 @@
+# Microsoft Developer Studio Project File - Name="nbdsrvr" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=nbdsrvr - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "nbdsrvr.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "nbdsrvr.mak" CFG="nbdsrvr - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "nbdsrvr - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "nbdsrvr - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "nbdsrvr - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x413 /d "NDEBUG"
+# ADD RSC /l 0x413 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "nbdsrvr - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x413 /d "_DEBUG"
+# ADD RSC /l 0x413 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "nbdsrvr - Win32 Release"
+# Name "nbdsrvr - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\nbdsrvr.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/winnbd/nbdsrvr.dsw b/winnbd/nbdsrvr.dsw
new file mode 100644 (file)
index 0000000..18f4634
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "nbdsrvr"=.\nbdsrvr.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/winnbd/readme.txt b/winnbd/readme.txt
new file mode 100644 (file)
index 0000000..d7c6a49
--- /dev/null
@@ -0,0 +1,31 @@
+nbdsrvr is (C) 2003 by folkert@vanheusden.com
+New versions can be obtained from:
+http://www.vanheusden.com/ (browse to the
+"microsoft windows software" section).
+
+Usage:
+
+nbdsrvr filename portnumber
+
+filename must be an image of a filesystem or
+whatever kind of device you whish to use. Can
+also be an empty file.
+For example, create an empty file of 10MB
+called "image.dat"
+Then:
+nbdsrvr image.dat 9000
+On your linux-box:
+nbd-client hostname 9000 /dev/ndX
+hostname is the hostname of your windows-box,
+/dev/ndX is the device you want to couple the
+image to.
+After that, you could create a filesystem on
+this image: on your Linux-box, type:
+mke2fs /dev/ndX
+and then mount it:
+mount /dev/ndX /mnt
+
+Good luck!
+
+
+-- Folkert van Heusden, 2003/07/13, 21:59