"Fossies" - the Fresh Open Source Software Archive

Member "coda-6.9.5/coda-src/venus/nt_util.cc" (17 Dec 2007, 6955 Bytes) of package /linux/misc/old/coda-6.9.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "nt_util.cc" see the Fossies "Dox" file reference documentation.

    1 /* BLURB gpl
    2 
    3                            Coda File System
    4                               Release 6
    5 
    6           Copyright (c) 1987-2003 Carnegie Mellon University
    7                   Additional copyrights listed below
    8 
    9 This  code  is  distributed "AS IS" without warranty of any kind under
   10 the terms of the GNU General Public Licence Version 2, as shown in the
   11 file  LICENSE.  The  technical and financial  contributors to Coda are
   12 listed in the file CREDITS.
   13 
   14                         Additional copyrights
   15                            none currently
   16 
   17 */
   18 
   19 #ifdef __CYGWIN32__
   20 
   21 #ifdef __cplusplus
   22 extern "C" {
   23 #endif
   24 
   25 #ifdef HAVE_CONFIG_H
   26 #include <config.h>
   27 #endif
   28 
   29 #include <stdio.h>
   30 #include <stdlib.h>
   31 #include <ctype.h>
   32 #include <windows.h>
   33 #include <winbase.h>
   34 #include <w32api/dbt.h>
   35 
   36 #include "coda_string.h"
   37 #include "coda.h"
   38 #include "util.h"
   39 
   40 #ifdef __cplusplus
   41 }
   42 #endif
   43 
   44 #include "nt_util.h"
   45 
   46 /*
   47  * NT specific routines 
   48  *
   49  */
   50 
   51 // Mounts ...
   52 
   53 // Parameters for nd_do_mounts ... both for direct call
   54 // and via CreateThread.
   55 static char drive;
   56 static int  mount;
   57 
   58 int
   59 wcslen (PWCHAR wstr)
   60 {
   61     int len = 0;
   62     while (*wstr++) len++;
   63     return len;
   64 }
   65 
   66 
   67 static DEV_BROADCAST_VOLUME DevBcst;
   68 
   69 
   70 // Can't use "normal" parameters due ot the fact that this will 
   71 // be called to start a new thread.  Use the static it for mount
   72 // communication.
   73 static DWORD
   74 nt_do_mounts (void *junk)
   75 {
   76     HANDLE h;
   77     OW_PSEUDO_MOUNT_INFO info;
   78     DWORD nBytesReturned;
   79     DWORD d;
   80     int ctlcode = OW_FSCTL_DISMOUNT_PSEUDO;
   81     
   82     WCHAR link[20] = L"\\??\\X:";  
   83     
   84     // Parameters ...
   85     link[4] = (short)drive;
   86     if (mount)
   87     ctlcode = OW_FSCTL_MOUNT_PSEUDO;
   88     
   89     d = DefineDosDevice(DDD_RAW_TARGET_PATH, "codadev", "\\Device\\codadev");
   90     if ( d == 0 ) {
   91     if (mount) {
   92         eprint ("DDD failed, mount failed.  Killing venus.");
   93         kill(getpid(), SIGKILL);
   94         exit(1);
   95     } else {
   96         eprint ("DDD failed, umount failed.");
   97         return 1;
   98     }
   99     }
  100 
  101     h = CreateFile ("\\\\.\\codadev", GENERIC_READ | GENERIC_WRITE,
  102             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  103             OPEN_EXISTING, 0, NULL);
  104 
  105     if (h == INVALID_HANDLE_VALUE) {
  106     if (mount) {
  107         eprint ("CreateFile failed, mount failed.  Killing venus.");
  108         kill(getpid(), SIGKILL);
  109         exit(1); 
  110     } else { 
  111         eprint ("CreateFile failed, umount failed.");
  112         return 1;
  113     }
  114     } 
  115     
  116     // Set up the info for the DeviceIoControl.
  117     info.PseudoVolumeHandle = (HANDLE*)(('C'<<24) + ('F'<<16) + ('S'<<8)
  118                     + (drive & 0xff)) ;
  119     info.PseudoDeviceName = L"\\Device\\coda";
  120     info.PseudoDeviceNameLength =
  121     wcslen(info.PseudoDeviceName) * sizeof(WCHAR);
  122     info.PseudoLinkName = link;
  123     info.PseudoLinkNameLength = wcslen(info.PseudoLinkName) * sizeof(WCHAR);
  124     
  125     d = DeviceIoControl(h, ctlcode, &info, sizeof(info), NULL, 0,
  126             &nBytesReturned, NULL);
  127     if (!d) {
  128     if (mount) {
  129         eprint ("Mount failed.  Killing venus.  (Error %d)",
  130             GetLastError());
  131         kill(getpid(), SIGKILL);
  132         exit(1);
  133     } else {
  134         eprint ("Umount failed. (Not a problem on startup.)");
  135         return 1;
  136     }
  137     } else {
  138         /* Let "others" know about the change! */
  139         DWORD BcstFlag;
  140     WPARAM ChKind;
  141 
  142         DevBcst.dbcv_devicetype = DBT_DEVTYP_VOLUME;
  143     DevBcst.dbcv_size = sizeof(DEV_BROADCAST_VOLUME);
  144     DevBcst.dbcv_flags = DBTF_NET;
  145     DevBcst.dbcv_unitmask =  1 << (toupper(drive) - 'A');
  146 
  147     if (mount)
  148         ChKind = DBT_DEVICEARRIVAL;
  149     else
  150         ChKind = DBT_DEVICEREMOVECOMPLETE;
  151     BcstFlag = BSM_ALLCOMPONENTS | BSM_ALLDESKTOPS;
  152 
  153     BroadcastSystemMessage (BSF_IGNORECURRENTTASK, &BcstFlag,
  154                     WM_DEVICECHANGE, ChKind, 
  155                     (LPARAM) &DevBcst);
  156     }
  157 
  158     return 0;
  159 }
  160 
  161 void nt_umount (const char *drivename)
  162 {
  163     drive = drivename[0];
  164     mount = 0;
  165     (void) nt_do_mounts (NULL);
  166 }
  167 
  168 void
  169 nt_mount (const char *drivename)
  170 {
  171     HANDLE h;
  172 
  173     nt_umount (drivename);
  174 
  175     mount = 1;
  176     
  177     h = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)nt_do_mounts, NULL, 0, NULL);
  178 
  179     if (!h) {
  180     eprint ("CreateThread failed.  Mount unsuccessful.  Killing venus.");
  181     kill(getpid(), SIGKILL);
  182     exit(1); 
  183     }
  184 
  185     CloseHandle (h);
  186 }
  187 
  188 //
  189 // kernel -> venus ... using a socket pair.
  190 //
  191 
  192 static int sockfd;
  193 static volatile int doexit;
  194 
  195 static DWORD
  196 listen_kernel (void *junk)
  197 {
  198     HANDLE h;
  199     int rc;
  200     DWORD bytesret;
  201     char outbuf[VC_MAXMSGSIZE];
  202 
  203     // Get the device ready;
  204     rc = DefineDosDevice(DDD_RAW_TARGET_PATH, "codadev", "\\Device\\codadev");
  205     if ( rc == 0 ) {
  206     eprint ("DDD failed, listen_kernel failed.");
  207     kill(getpid(), SIGKILL);
  208     exit(1); 
  209     }
  210 
  211     h = CreateFile ("\\\\.\\codadev", GENERIC_READ | GENERIC_WRITE,
  212             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  213             OPEN_EXISTING, 0, NULL);
  214 
  215     if (h == INVALID_HANDLE_VALUE) {
  216     eprint ("CreateFile failed, listen_kernel failed.");
  217     kill(getpid(), SIGKILL);
  218     exit(1); 
  219     } 
  220 
  221     while (1) {
  222     // Do a device ioctl.
  223     bytesret = 0;
  224     rc = DeviceIoControl (h, CODA_FSCTL_FETCH, NULL, 0, outbuf,
  225                   VC_MAXMSGSIZE, &bytesret, NULL);
  226     if (rc) {
  227         if (bytesret > 0) {
  228         write (sockfd, (char *)&bytesret, sizeof(bytesret));
  229         write (sockfd, outbuf, bytesret);
  230         }
  231     } else {
  232         eprint ("listen_kernel: fetch failed");
  233     }
  234     if (doexit)
  235       ExitThread(0);
  236     }
  237 }
  238 
  239 // "public" interface for ipc
  240 
  241 static HANDLE kerndev;
  242 static HANDLE kernelmon;
  243 
  244 int nt_initialize_ipc (int sock)
  245 {
  246     int rc;
  247 
  248     // Get the device ready for writing to kernel
  249     rc = DefineDosDevice(DDD_RAW_TARGET_PATH, "codadev", "\\Device\\codadev");
  250     if ( rc == 0 ) {
  251     eprint ("nt_initialize_ipc: DDD failed.");
  252     return 0; 
  253     }
  254 
  255     kerndev = CreateFile ("\\\\.\\codadev", GENERIC_READ | GENERIC_WRITE,
  256               FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  257               OPEN_EXISTING, 0, NULL);
  258 
  259     if (kerndev == INVALID_HANDLE_VALUE) {
  260         int rv ;
  261 
  262     eprint ("nt_initialize_ipc: trying to start coda file system.");
  263     rv = system ("net start coda");  // Ignore value.
  264     kerndev = CreateFile ("\\\\.\\codadev", GENERIC_READ | GENERIC_WRITE,
  265                   FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  266                   OPEN_EXISTING, 0, NULL);
  267 
  268     if (kerndev == INVALID_HANDLE_VALUE) {
  269         
  270         eprint ("nt_initialize_ipc: CreateFile failed. "
  271             "Is the coda installed properly?");
  272         return 0; 
  273     }
  274     } 
  275 
  276     // Other initialization
  277     sockfd = sock;
  278     doexit = 0;
  279 
  280     // Start the kernel monitor
  281     kernelmon = CreateThread (0, 0, (LPTHREAD_START_ROUTINE)listen_kernel, NULL, 0, NULL);
  282     if (kernelmon == NULL) {
  283     return 0;
  284     }
  285 
  286     // All was successful 
  287     return 1;
  288 }
  289 
  290 int nt_msg_write (const char *buf, int size)
  291 {
  292     int rc;
  293     DWORD bytesret;
  294 
  295     //    eprint ("nt_msg_write: Start\n");
  296     rc = DeviceIoControl (kerndev, CODA_FSCTL_ANSWER, (char*)buf, size, NULL, 0,
  297               &bytesret, NULL);
  298     //    eprint ("nt_msg_write: End\n");
  299     if (!rc)
  300     return 0;
  301     
  302     return size;
  303 }
  304 
  305 void nt_stop_ipc (void)
  306 {
  307     (void) TerminateThread (kernelmon,  0);
  308     CloseHandle(kernelmon);
  309     doexit = 1;
  310 }
  311 
  312 #endif