]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 2306] Added user-mode/loop-back PPS API provider for Win32
authorJuergen Perlinger <perlinger@ntp.org>
Sun, 18 Nov 2012 11:15:34 +0000 (12:15 +0100)
committerJuergen Perlinger <perlinger@ntp.org>
Sun, 18 Nov 2012 11:15:34 +0000 (12:15 +0100)
bk: 50a8c3566vIgGiWriGNwooWEf3lrXQ

23 files changed:
ChangeLog
include/ntp_refclock.h
ports/winnt/include/ntp_iocompletionport.h
ports/winnt/include/termios.h
ports/winnt/libntp/termios.c
ports/winnt/ntpd/ntp_iocompletionport.c
ports/winnt/ppsapi/loopback/monolithic-serialpps-timepps.h [new file with mode: 0644]
ports/winnt/ppsapi/loopback/monolithic-serialpps-timepps.txt [new file with mode: 0644]
ports/winnt/ppsapi/loopback/src/loopback-ppsapi.c [new file with mode: 0644]
ports/winnt/ppsapi/loopback/src/loopback-ppsapi.def [new file with mode: 0644]
ports/winnt/ppsapi/loopback/src/loopback-ppsapi.h [new file with mode: 0644]
ports/winnt/ppsapi/loopback/src/sys/time.h [new file with mode: 0644]
ports/winnt/ppsapi/loopback/src/timepps.h [new file with mode: 0644]
ports/winnt/vs2008/instsrv/instsrv.vcproj
ports/winnt/vs2008/libntp/libntp.vcproj
ports/winnt/vs2008/loopback-pps/loopback-ppsapi-provider.vcproj [new file with mode: 0644]
ports/winnt/vs2008/ntp-keygen/ntp-keygen.vcproj
ports/winnt/vs2008/ntp.sln
ports/winnt/vs2008/ntpd-keyword-gen/ntpd-keyword-gen.vcproj
ports/winnt/vs2008/ntpd/ntpd.vcproj
ports/winnt/vs2008/ntpdate/ntpdate.vcproj
ports/winnt/vs2008/ntpdc/ntpdc.vcproj
ports/winnt/vs2008/ntpq/ntpq.vcproj

index afdba49dc253bdd120743e9442acf4881a6c8c8f..a2f019a4ba126bff3fa2b9e866263e234dfa4885 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+* [Bug 2306] Added user-mode/loop-back PPS API provider for Win32
 * html/ updates from Dave Mills.
 * [Bug 1223] Allow configurable values for RLIMIT_STACK and
   RLIMIT_MEMLOCK.
index b168d243cf1a081174436652d2f9569600efdac6..f92d14cdb890c275d2e38bde1fcd491cf045ac61 100644 (file)
@@ -103,6 +103,10 @@ struct refclockio {
        int     fd;             /* file descriptor */
        u_long  recvcount;      /* count of receive completions */
        int     active;         /* nonzero when in use */
+
+#ifdef HAVE_IO_COMPLETION_PORT
+       void *  device_context; /* device-related data for i/o subsystem */
+#endif
 };
 
 /*
index a32476f98ac8ee2468c1174ac4b0dfef79df3710..7d7ff7c4b207a62b3ef201a8aa85e119e05113b6 100644 (file)
@@ -15,6 +15,7 @@ extern        int     io_completion_port_add_socket(SOCKET fd, struct interface *);
 
 struct refclockio; /* in ntp_refclock.h but inclusion here triggers problems */
 extern int     io_completion_port_add_clock_io(struct refclockio *rio);
+extern void    io_completion_port_remove_clock_io(struct refclockio *rio);
 extern int     io_completion_port_sendto(int, void *, size_t, sockaddr_u *);
 
 extern int     GetReceivedBuffers(void);
index 350ee47fb88d2763a21d44b8899fd08c294588ff..9c1cc625cd40eaa38a7e5e212d52b30ca4c386cb 100644 (file)
@@ -209,5 +209,6 @@ extern      int     ioctl           (int, int, int *);
 extern int     tcsetattr       (int, int, const struct termios *);
 extern int     tcgetattr       (int, struct termios *);
 extern int     tcflush         (int, int);
+extern int     isserialhandle  (HANDLE);
 
 #endif /* NTP_WIN_TERMIOS_H */
index db9895bed82aec262ecfc4eb362a13b41b529ef2..d0e1351dc5e3a49be8db0be29e2f0f60a99cd07f 100644 (file)
@@ -180,6 +180,24 @@ closeserial(int fd)
        return close(fd);
 }
 
+/*
+ * isserialhandle() -- check if a handle is a COM port handle
+ */
+int isserialhandle(
+       HANDLE h
+       )
+{
+       size_t  u;
+       size_t  d;
+
+
+       for (u = 0; u < c_hnds; u++)
+               for (d = 0; d < hnds[u].opens; d++)
+                       if (hnds[u].dupes[d] == h)
+                               return TRUE;
+       return FALSE;
+}
+
 
 /*
  * tty_open - open serial port for refclock special uses
index 9e3e541f345f966317b53672c112ad879391718d..031c34c4b997f133db42a467329f06345158a388 100644 (file)
@@ -37,9 +37,12 @@ Some notes on the implementation:
   objects. Leak tracing becomes more interesting, though.
 
 
-The current implementation is based on the work of Danny Mayer who wrote
+The current implementation is based on the work of Danny Mayer who improved
 the original implementation and Dave Hart who improved on the serial I/O
-routines.  This version still provides the 'user space PPS' emulation
+routines. The true roots of this file seem to be shrouded by the mist of time...
+
+
+This version still provides the 'user space PPS' emulation
 feature.
 
 Juergen Perlinger (perlinger@ntp.org) Feb 2012
@@ -74,6 +77,44 @@ Juergen Perlinger (perlinger@ntp.org) Feb 2012
 # pragma warning(disable: 201)         /* nonstd extension nameless union */
 #endif
 
+/*
+ * ---------------------------------------------------------------------
+ * storage type for PPS data (DCD change counts & times)
+ * ---------------------------------------------------------------------
+ */
+struct PpsData {
+       u_long  cc_assert;
+       u_long  cc_clear;
+       l_fp    ts_assert;
+       l_fp    ts_clear;
+};
+typedef struct PpsData PPSData_t;
+
+struct PpsDataEx {
+       u_long          cov_count;
+       PPSData_t       data;
+};
+typedef volatile struct PpsDataEx PPSDataEx_t;
+
+/*
+ * ---------------------------------------------------------------------
+ * device context; uses reference counting to avoid nasty surprises.
+ * Currently this stores only the PPS time stamps, but it could be
+ * easily extended.
+ * ---------------------------------------------------------------------
+ */
+#define PPS_QUEUE_LEN  8u                /* must be power of two! */
+#define PPS_QUEUE_MSK  (PPS_QUEUE_LEN-1) /* mask for easy MOD ops */
+
+struct DeviceContext {
+       volatile long   ref_count;
+       volatile u_long cov_count;
+       PPSData_t       pps_data;
+       PPSDataEx_t     pps_buff[PPS_QUEUE_LEN];
+};
+
+typedef struct DeviceContext DevCtx_t;
+
 /*
  * ---------------------------------------------------------------------
  * I/O context structure
@@ -88,8 +129,9 @@ Juergen Perlinger (perlinger@ntp.org) Feb 2012
  * finally needed for the processing of the buffer.
  * ---------------------------------------------------------------------
  */
-struct IoCtx;
-typedef struct IoCtx IoCtx_t;
+//struct IoCtx;
+typedef struct IoCtx      IoCtx_t;
+typedef struct refclockio RIO_t;
 
 typedef void (*IoCompleteFunc)(ULONG_PTR, IoCtx_t *);
 
@@ -98,10 +140,13 @@ struct IoCtx {
        union {
                recvbuf_t *     recv_buf;       /* incoming -> buffer structure */
                void *          trans_buf;      /* outgoing -> char array       */
+               PPSData_t *     pps_buf;        /* for reading PPS seq/stamps   */
+               HANDLE          ppswake;        /* pps wakeup for attach        */
        };
        IoCompleteFunc          onIoDone;       /* HL callback to execute       */
-       struct refclockio *     rio;            /* RIO backlink (for offload)   */
-       l_fp                    DCDSTime;       /* timestamp of DCD set         */
+       RIO_t *                 rio;            /* RIO backlink (for offload)   */
+       DevCtx_t *              devCtx;
+       l_fp                    DCDSTime;       /* PPS-hack: time of DCD ON     */
        l_fp                    FlagTime;       /* timestamp of flag/event char */
        l_fp                    RecvTime;       /* timestamp of callback        */
        DWORD                   errCode;        /* error code of last I/O       */
@@ -123,10 +168,10 @@ static            void ntpd_addremove_semaphore(HANDLE, int);
 static inline  void set_serial_recv_time    (recvbuf_t *, IoCtx_t *);
 
 /* Initiate/Request async IO operations */
-static BOOL QueueSerialWait   (struct refclockio *, recvbuf_t *, IoCtx_t *);
-static BOOL QueueSerialRead   (struct refclockio *, recvbuf_t *, IoCtx_t *);
-static BOOL QueueRawSerialRead(struct refclockio *, recvbuf_t *, IoCtx_t *);
-static  BOOL QueueSocketRecv   (SOCKET             , recvbuf_t *, IoCtx_t *);
+static BOOL QueueSerialWait   (RIO_t *, recvbuf_t *, IoCtx_t *);
+static BOOL QueueSerialRead   (RIO_t *, recvbuf_t *, IoCtx_t *);
+static BOOL QueueRawSerialRead(RIO_t *, recvbuf_t *, IoCtx_t *);
+static  BOOL QueueSocketRecv   (SOCKET , recvbuf_t *, IoCtx_t *);
 
 
 /* High-level IO callback functions */
@@ -198,36 +243,143 @@ IoCtxPoolDone(void)
 
 /*
  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * Alloc & Free
+ * Alloc & Free on local heap
  *
  * When the heap handle is NULL, these both will fail; Alloc with a NULL
  * return and Free silently.
  */
-static IoCtx_t *
-IoCtxAlloc(void)
+static void * __fastcall
+LocalPoolAlloc(
+       size_t          size,
+       const char *    desc
+)
 {
-       IoCtx_t *       lpo;
+       void *  ptr;
 
-       if (hHeapHandle) {
-               lpo = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(IoCtx_t));
-       } else {
-               lpo = NULL;
+       /* Windows heaps can't grok zero byte allocation.
+        * We just get one byte.
+        */
+       if (size == 0)
+               size = 1;
+       if (hHeapHandle != NULL)
+               ptr = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, size);
+       else
+               ptr = NULL;
+       DPRINTF(3, ("Allocate '%s', heap=%p, ptr=%p\n",
+                       desc,  hHeapHandle, ptr));
+
+       return ptr;
+}
+
+static void __fastcall
+LocalPoolFree(
+       void *          ptr,
+       const char *    desc
+       )
+{
+       DPRINTF(3, ("Free '%s', heap=%p, ptr=%p\n",
+                       desc, hHeapHandle, ptr));
+       if (ptr != NULL && hHeapHandle != NULL)
+               HeapFree(hHeapHandle, 0, ptr);
+}
+
+/*
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ * Alloc & Free of Device context
+ *
+ * When the heap handle is NULL, these both will fail; Alloc with a NULL
+ * return and Free silently.
+ */
+static DevCtx_t * __fastcall
+DevCtxAlloc(void)
+{
+       DevCtx_t *      devCtx;
+       u_long          slot;
+
+       /* allocate struct and tag all slots as invalid */
+       devCtx = (DevCtx_t *)LocalPoolAlloc(sizeof(DevCtx_t), "DEV ctx");
+       if (devCtx != NULL)
+       {
+               devCtx->cov_count = ~0ul;
+               for (slot = 0; slot < PPS_QUEUE_LEN; slot++)
+                       devCtx->pps_buff[slot].cov_count = ~slot;
        }
-       DPRINTF(3, ("Allocate IO ctx, heap=%p, ptr=%p\n", hHeapHandle, lpo));
+       return devCtx;
+}
+
+static void __fastcall
+DevCtxFree(
+       DevCtx_t *      devCtx
+       )
+{
+       /* this would be the place to get rid of managed ressources. */
+       LocalPoolFree(devCtx, "DEV ctx");
+}
 
-       return lpo;
+static DevCtx_t * __fastcall
+DevCtxAttach(
+       DevCtx_t *      devCtx
+       )
+{
+       if (devCtx != NULL)
+               InterlockedIncrement(&devCtx->ref_count);
+       return devCtx;
 }
 
-static void
+static void __fastcall
+DevCtxDetach(
+       DevCtx_t *      devCtx
+       )
+{
+       if (devCtx && !InterlockedDecrement(&devCtx->ref_count))
+               DevCtxFree(devCtx);
+}
+
+/*
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ * Alloc & Free of I/O context
+ *
+ * When the heap handle is NULL, these both will fail; Alloc with a NULL
+ * return and Free silently.
+ */
+static IoCtx_t * __fastcall
+IoCtxAlloc(
+       DevCtx_t *      devCtx
+       )
+{
+       IoCtx_t *       ioCtx;
+
+       ioCtx = (IoCtx_t *)LocalPoolAlloc(sizeof(IoCtx_t), "IO ctx");
+       if (ioCtx != NULL)
+               ioCtx->devCtx = DevCtxAttach(devCtx);
+       return ioCtx;
+}
+
+static void __fastcall
 IoCtxFree(
-       IoCtx_t *lpo
+       IoCtx_t *       ctx
        )
 {
-       DPRINTF(3, ("Free IO ctx, heap=%p, ptr=%p\n", hHeapHandle, lpo));
-       if (lpo != NULL && hHeapHandle != NULL)
-               HeapFree(hHeapHandle, 0, lpo);
+       if (ctx)
+               DevCtxDetach(ctx->devCtx);
+       LocalPoolFree(ctx, "IO ctx");
 }
 
+static void __fastcall
+IoCtxReset(
+       IoCtx_t *       ctx
+       )
+{
+       RIO_t *         rio;
+       DevCtx_t *      dev;
+       if (ctx) {
+               rio = ctx->rio;
+               dev = ctx->devCtx;
+               ZERO(*ctx);
+               ctx->rio    = rio;
+               ctx->devCtx = dev;
+       }
+}
 
 /*
  * -------------------------------------------------------------------
@@ -551,9 +703,9 @@ IoResultCheck(
 
 static BOOL
 QueueSerialWait(
-       struct refclockio *     rio,
-       recvbuf_t *             buff,
-       IoCtx_t *               lpo
+       RIO_t *         rio,
+       recvbuf_t *     buff,
+       IoCtx_t *       lpo
        )
 {
        BOOL   rc;
@@ -580,19 +732,24 @@ OnSerialWaitComplete(
        IoCtx_t *       lpo
        )
 {
-       struct refclockio *     rio;
-       recvbuf_t *             buff;
-       DWORD                   modem_status;
+       RIO_t *         rio;
+       DevCtx_t *      dev;
+       recvbuf_t *     buff;
+       PPSDataEx_t *   ppsbuf;
+       DWORD           modem_status;
+       u_long          covc;
 
        /* check and bail out if operation failed */
        if (!IoResultCheck(lpo->errCode, lpo,
-                          "WaitCommEvent failed"))
+               "WaitCommEvent failed"))
                return;
 
        /* get & validate context and buffer. */
-       rio  = lpo->rio;
+       rio  = (RIO_t *)key;
        buff = lpo->recv_buf;
-       NTP_INSIST((ULONG_PTR)rio == key);
+       dev  = lpo->devCtx;
+
+       NTP_INSIST(rio == lpo->rio);
 
 #ifdef DEBUG
        if (~(EV_RXFLAG | EV_RLSD | EV_RXCHAR) & lpo->com_events) {
@@ -607,15 +764,46 @@ OnSerialWaitComplete(
         * this code that makes a lot of sense: move to a putative
         * dcdpps-ppsapi-provider.dll.
         */
-       if (EV_RLSD & lpo->com_events) { 
+       if ((EV_RLSD & lpo->com_events) && dev) {
                modem_status = 0;
                GetCommModemStatus((HANDLE)_get_osfhandle(rio->fd),
                                   &modem_status);
-               if (MS_RLSD_ON & modem_status) {
-                       lpo->DCDSTime = lpo->RecvTime;
-                       lpo->flTsDCDS = 1;
-                       DPRINTF(2, ("fd %d DCD PPS at %s\n", rio->fd,
-                                   ulfptoa(&lpo->RecvTime, 6)));
+
+               if (dev != NULL) {
+                       /* PPS-context available -- use it! */
+                       if (MS_RLSD_ON & modem_status) {
+                               dev->pps_data.cc_assert++;
+                               dev->pps_data.ts_assert = lpo->RecvTime;
+                               DPRINTF(2, ("upps-real: fd %d DCD PPS Rise at %s\n", rio->fd,
+                                       ulfptoa(&lpo->RecvTime, 6)));
+                       } else {
+                               dev->pps_data.cc_clear++;
+                               dev->pps_data.ts_clear = lpo->RecvTime;
+                               DPRINTF(2, ("upps-real: fd %d DCD PPS Fall at %s\n", rio->fd,
+                                       ulfptoa(&lpo->RecvTime, 6)));
+                       }
+                       /*
+                       ** Update PPS buffer, writing from low to high, with index
+                       ** update as last action. We need barriers to make sure that
+                       ** the compiler does not shuffle the assignments and that the
+                       ** data becomes visible to other threads in exactly that order.
+                       ** The lock-free read/write queue depends on that order!
+                       */
+                       covc   = dev->cov_count + 1u;
+                       ppsbuf = dev->pps_buff + (covc & PPS_QUEUE_MSK);
+                       ppsbuf->cov_count = covc;
+                       _WriteBarrier();
+                       ppsbuf->data = dev->pps_data;
+                       InterlockedExchange((PLONG)&dev->cov_count, covc);
+                       /* Note: InterlockedExchange() is a full barrier. */
+               } else {
+                       /* backward compat: 'usermode-pps-hack' */
+                       if (MS_RLSD_ON & modem_status) {
+                               lpo->DCDSTime = lpo->RecvTime;
+                               lpo->flTsDCDS = 1;
+                               DPRINTF(2, ("upps-hack: fd %d DCD PPS Rise at %s\n", rio->fd,
+                                       ulfptoa(&lpo->RecvTime, 6)));
+                       }
                }
        }
 
@@ -633,7 +821,6 @@ OnSerialWaitComplete(
        }
 }
 
-
 /*
  * -------------------------------------------------------------------
  * Serial IO stuff
@@ -651,9 +838,9 @@ OnSerialWaitComplete(
  */
 static BOOL
 QueueSerialRead(
-       struct refclockio *     rio,
-       recvbuf_t *             buff,
-       IoCtx_t *               lpo
+       RIO_t *         rio,
+       recvbuf_t *     buff,
+       IoCtx_t *       lpo
        )
 {
        BOOL   rc;
@@ -685,8 +872,8 @@ OnSerialReadComplete(
        IoCtx_t *       lpo
        )
 {
-       struct refclockio *     rio;
-       recvbuf_t *             buff;
+       RIO_t *         rio;
+       recvbuf_t *     buff;
 
        /* check and bail out if operation failed */
        if (!IoResultCheck(lpo->errCode, lpo,
@@ -702,7 +889,7 @@ OnSerialReadComplete(
        if (!QueueUserWorkItem(&OnSerialReadWorker, lpo, WT_EXECUTEDEFAULT)) {
                msyslog(LOG_ERR,
                        "Can't offload to worker thread, will skip data: %m");
-               ZERO(*lpo);
+               IoCtxReset(lpo);
                buff->recv_length = 0;
                QueueSerialWait(rio, buff, lpo);
        }
@@ -722,12 +909,12 @@ OnSerialReadComplete(
 static DWORD WINAPI
 OnSerialReadWorker(void * ctx)
 {
-       IoCtx_t *               lpo;
-       recvbuf_t *             buff, *obuf;
-       struct refclockio *     rio;
-       char                    *sptr, *send, *dptr;
-       BOOL                    eol;
-       char                    ch;
+       IoCtx_t *       lpo;
+       recvbuf_t *     buff, *obuf;
+       RIO_t *         rio;
+       char            *sptr, *send, *dptr;
+       BOOL            eol;
+       char            ch;
 
        /* Get context back */
        lpo  = (IoCtx_t*)ctx;
@@ -812,7 +999,7 @@ OnSerialReadWorker(void * ctx)
                buff->recv_length = 0;
        }
 
-       ZERO(*lpo);
+       IoCtxReset(lpo);
        QueueSerialWait(rio, buff, lpo);
        return 0;
 }
@@ -831,9 +1018,9 @@ OnSerialReadWorker(void * ctx)
 
 static BOOL
 QueueRawSerialRead(
-       struct refclockio *     rio,
-       recvbuf_t *             buff,
-       IoCtx_t *               lpo
+       RIO_t *         rio,
+       recvbuf_t *     buff,
+       IoCtx_t *       lpo
        )
 {
        BOOL   rc;
@@ -861,8 +1048,8 @@ OnRawSerialReadComplete(
        IoCtx_t *       lpo
        )
 {
-       struct refclockio *     rio;
-       recvbuf_t *             buff;
+       RIO_t *         rio;
+       recvbuf_t *     buff;
 
        /* check and bail out if operation failed */
        if (!IoResultCheck(lpo->errCode, lpo,
@@ -938,7 +1125,7 @@ async_write(
        IoCtx_t *       lpo;
        BOOL            rc;
 
-       lpo  = IoCtxAlloc();
+       lpo  = IoCtxAlloc(NULL);
        if (lpo == NULL) {
                DPRINTF(1, ("async_write: out of memory\n"));
                errno = ENOMEM;
@@ -968,7 +1155,7 @@ OnSerialWriteComplete(
        )
 {
        /* set RIO and force silent cleanup if no error */
-       lpo->rio = (struct refclockio *)key;
+       lpo->rio = (RIO_t *)key;
        if (ERROR_SUCCESS == lpo->errCode)
                lpo->errCode = ERROR_OPERATION_ABORTED;
        IoResultCheck(lpo->errCode, lpo,
@@ -976,7 +1163,123 @@ OnSerialWriteComplete(
 }
 
 
+/*
+ * -------------------------------------------------------------------
+ * Serial IO stuff
+ *
+ * Part 5 -- read PPS time stamps
+ *
+ * -------------------------------------------------------------------
+ */
+
+/* The dummy read procedure is used for getting the device context
+ * into the IO completion thread, using the IO completion queue for
+ * transport. There are other ways to accomplish what we need here,
+ * but using the IO machine is handy and avoids a lot of trouble.
+ */
+static void
+OnPpsDummyRead(
+       ULONG_PTR       key,
+       IoCtx_t *       lpo
+       )
+{
+       RIO_t * rio;
+
+       rio = (RIO_t *)key;
+       lpo->devCtx = DevCtxAttach(rio->device_context);
+       SetEvent(lpo->ppswake);
+}
+
+__declspec(dllexport) void* __stdcall
+ntp_pps_attach_device(
+       HANDLE  hndIo
+       )
+{
+       IoCtx_t         myIoCtx;
+       HANDLE          myEvt;
+       DevCtx_t *      dev;
+       DWORD           rc;
+
+       if (!isserialhandle(hndIo)) {
+               SetLastError(ERROR_INVALID_HANDLE);
+               return NULL;
+       }
+
+       ZERO(myIoCtx);
+       dev   = NULL;
+       myEvt = CreateEvent(NULL, FALSE, FALSE, NULL);
+       if (NULL == myEvt)
+               goto done;
+
+       myIoCtx.ppswake   = myEvt;
+       myIoCtx.onIoDone  = OnPpsDummyRead;
+       rc = ReadFile(hndIo, &myIoCtx.byteCount, 0,
+                       &myIoCtx.byteCount, &myIoCtx.ol);
+       if (!rc && (GetLastError() != ERROR_IO_PENDING))
+               goto done;
+       if (WaitForSingleObject(myEvt, INFINITE) == WAIT_OBJECT_0)
+               if (NULL == (dev = myIoCtx.devCtx))
+                       SetLastError(ERROR_INVALID_HANDLE);
+done:
+       rc = GetLastError();
+       CloseHandle(myEvt);
+       SetLastError(rc);
+       return dev;
+}
+
+__declspec(dllexport) void __stdcall
+ntp_pps_detach_device(
+       DevCtx_t *      dev
+       )
+{
+       DevCtxDetach(dev);
+}
 
+__declspec(dllexport) BOOL __stdcall
+ntp_pps_read(
+       DevCtx_t *      dev,
+       PPSData_t *     data,
+       size_t          dlen
+       )
+{
+       u_long          guard, covc;
+       int             repc;
+       PPSDataEx_t *   ppsbuf;
+
+
+       if (dev == NULL) {
+               SetLastError(ERROR_INVALID_HANDLE);
+               return FALSE;
+       }
+       if (data == NULL || dlen != sizeof(PPSData_t)) {
+               SetLastError(ERROR_INVALID_PARAMETER);
+               return FALSE;
+       }
+       /*
+       ** Reading from shared memory in a lock-free fashion can be
+       ** a bit tricky, since we have to read the components in the
+       ** opposite direction from the write, and the compiler must
+       ** not reorder the read sequence.
+       ** We use read barriers and a volatile data source to avoid
+       ** reordering on compiler and CPU level.
+       */
+       repc = 3;
+       do {
+               covc = dev->cov_count;
+               _ReadBarrier();
+               ppsbuf = dev->pps_buff + ((covc >> 1) & PPS_QUEUE_MSK);
+               *data = ppsbuf->data;
+               _ReadBarrier();
+               guard = covc ^ ppsbuf->cov_count;
+               _ReadBarrier();
+       } while ((guard != 0u) && ((guard & PPS_QUEUE_MSK) == 0u) && --repc);
+
+       if (guard != 0u) {
+               SetLastError(ERROR_INVALID_DATA);
+               return FALSE;
+       }
+       return TRUE;
+}
 
 /*
  * Add a reference clock data structures I/O handles to
@@ -984,10 +1287,11 @@ OnSerialWriteComplete(
  */  
 int
 io_completion_port_add_clock_io(
-       struct refclockio *rio
+       RIO_t *rio
        )
 {
        IoCtx_t *       lpo;
+       DevCtx_t *      dev;
        recvbuf_t *     buff;
        HANDLE          h;
 
@@ -1001,7 +1305,13 @@ io_completion_port_add_clock_io(
                return 1;
        }
 
-       lpo = IoCtxAlloc();
+       dev = DevCtxAlloc();
+       if (NULL == dev) {
+               msyslog(LOG_ERR, "Can't allocate device context for i/o completion port: %m");
+               return 1;
+       }
+       rio->device_context = DevCtxAttach(dev);
+       lpo = IoCtxAlloc(dev);
        if (NULL == lpo) {
                msyslog(LOG_ERR, "Can't allocate heap for completion port: %m");
                return 1;
@@ -1013,6 +1323,15 @@ io_completion_port_add_clock_io(
        return 0;
 }
 
+void
+io_completion_port_remove_clock_io(
+       RIO_t *rio
+       )
+{
+       if (rio)
+               DevCtxDetach((DevCtx_t *)rio->device_context);
+}
+
 /*
  * Queue a receiver on a socket. Returns 0 if no buffer can be queued 
  *
@@ -1157,7 +1476,7 @@ io_completion_port_add_socket(
        for (n = 0; n < WINDOWS_RECVS_PER_SOCKET; n++) {
 
                buff = get_free_recv_buffer_alloc();
-               lpo = IoCtxAlloc();
+               lpo = IoCtxAlloc(NULL);
                if (lpo == NULL)
                {
                        msyslog(LOG_ERR
diff --git a/ports/winnt/ppsapi/loopback/monolithic-serialpps-timepps.h b/ports/winnt/ppsapi/loopback/monolithic-serialpps-timepps.h
new file mode 100644 (file)
index 0000000..62159fc
--- /dev/null
@@ -0,0 +1,714 @@
+/***********************************************************************
+ *                                                                    *
+ * Copyright (c) David L. Mills 1999-2000                             *
+ *                                                                    *
+ * Permission to use, copy, modify, and distribute this software and   *
+ * its documentation for any purpose and without fee is hereby        *
+ * granted, provided that the above copyright notice appears in all    *
+ * copies and that both the copyright notice and this permission       *
+ * notice appear in supporting documentation, and that the name        *
+ * University of Delaware not be used in advertising or publicity      *
+ * pertaining to distribution of the software without specific,        *
+ * written prior permission. The University of Delaware makes no       *
+ * representations about the suitability this software for any        *
+ * purpose. It is provided "as is" without express or implied          *
+ * warranty.                                                          *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * This header file complies with "Pulse-Per-Second API for UNIX-like  *
+ * Operating Systems, Version 1.0", rfc2783. Credit is due Jeff Mogul  *
+ * and Marc Brett, from whom much of this code was shamelessly stolen. *
+ *                                                                    *
+ * This modified timepps.h can be used to provide a PPSAPI interface   *
+ * to a machine running Windows with a suitably modified              *
+ * serialpps.sys being used in place of serial.sys.  It can           *
+ * be extended to support a modified parallel port driver once        *
+ * available.                                                         *
+ *                                                                    *
+ * This Windows version was derived by Dave Hart                      *
+ * <davehart@davehart.com> from Mills' timepps-Solaris.h              *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * Some of this include file                                          *
+ * Copyright (c) 1999 by Ulrich Windl,                                *
+ *     based on code by Reg Clemens <reg@dwf.com>                     *
+ *             based on code by Poul-Henning Kamp <phk@FreeBSD.org>   *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * "THE BEER-WARE LICENSE" (Revision 42):                              *
+ * <phk@FreeBSD.org> wrote this file.  As long as you retain this      *
+ * notice you can do whatever you want with this stuff. If we meet some*
+ * day, and you think this stuff is worth it, you can buy me a beer    *
+ * in return.  Poul-Henning Kamp                                      *
+ *                                                                    *
+ **********************************************************************/
+
+#ifndef _SYS_TIMEPPS_H_
+#define _SYS_TIMEPPS_H_
+
+/* Implementation note: the logical states ``assert'' and ``clear''
+ * are implemented in terms of the UART register, i.e. ``assert''
+ * means the bit is set.
+ */
+
+/*
+ * The following definitions are architecture independent
+ */
+
+#define PPS_API_VERS_1         1               /* API version number */
+#define PPS_JAN_1970           2208988800UL    /* 1970 - 1900 in seconds */
+#define PPS_NANOSECOND         1000000000L     /* one nanosecond in decimal */
+#define PPS_FRAC               4294967296.     /* 2^32 as a double */
+#define PPS_HECTONANOSECONDS   10000000        /* 100ns units in a second */
+#define PPS_FILETIME_1970      0x019db1ded53e8000 /* unix epoch to Windows */
+
+#define PPS_NORMALIZE(x)       /* normalize timespec */ \
+       do { \
+               if ((x).tv_nsec >= PPS_NANOSECOND) { \
+                       (x).tv_nsec -= PPS_NANOSECOND; \
+                       (x).tv_sec++; \
+               } else if ((x).tv_nsec < 0) { \
+                       (x).tv_nsec += PPS_NANOSECOND; \
+                       (x).tv_sec--; \
+               } \
+       } while (0)
+
+#define PPS_TSPECTONTP(x)      /* convert timespec to ntp_fp */ \
+       do { \
+               double d_temp; \
+       \
+               (x).integral += (unsigned int)PPS_JAN_1970; \
+               d_temp = (x).fractional * PPS_FRAC / PPS_NANOSECOND; \
+               if (d_temp >= PPS_FRAC) \
+                       (x).integral++; \
+               (x).fractional = (unsigned int)d_temp; \
+       } while (0)
+
+#define PPS_NTPTOTSPEC(x)      /* convert ntp_fp to timespec */ \
+       do { \
+               double d_temp; \
+       \
+               (x).tv_sec -= (time_t)PPS_JAN_1970; \
+               d_temp = (double)((x).tv_nsec); \
+               d_temp *= PPS_NANOSECOND; \
+               d_temp /= PPS_FRAC; \
+               (x).tv_nsec = (long)d_temp; \
+       } while (0) 
+
+
+/*
+ * Device/implementation parameters (mode)
+ */
+
+#define PPS_CAPTUREASSERT      0x01    /* capture assert events */
+#define PPS_CAPTURECLEAR       0x02    /* capture clear events */
+#define PPS_CAPTUREBOTH        0x03    /* capture assert and clear events */
+
+#define PPS_OFFSETASSERT       0x10    /* apply compensation for assert ev. */
+#define PPS_OFFSETCLEAR        0x20    /* apply compensation for clear ev. */
+#define PPS_OFFSETBOTH         0x30    /* apply compensation for both */
+
+#define PPS_CANWAIT            0x100   /* Can we wait for an event? */
+#define PPS_CANPOLL            0x200   /* "This bit is reserved for */
+
+/*
+ * Kernel actions (mode)
+ */
+
+#define PPS_ECHOASSERT         0x40    /* feed back assert event to output */
+#define PPS_ECHOCLEAR          0x80    /* feed back clear event to output */
+
+/*
+ * Timestamp formats (tsformat)
+ */
+
+#define PPS_TSFMT_TSPEC        0x1000  /* select timespec format */
+#define PPS_TSFMT_NTPFP        0x2000  /* select NTP format */
+
+/*
+ * Kernel discipline actions (not used in Windows yet)
+ */
+
+#define PPS_KC_HARDPPS         0       /* enable kernel consumer */
+#define PPS_KC_HARDPPS_PLL     1       /* phase-lock mode */
+#define PPS_KC_HARDPPS_FLL     2       /* frequency-lock mode */
+
+/*
+ * Type definitions
+ */
+
+typedef unsigned long pps_seq_t;       /* sequence number */
+
+#pragma warning(push)
+#pragma warning(disable: 201)          /* nonstd extension nameless union */
+
+typedef struct ntp_fp {
+       union ntp_fp_sec {
+               unsigned int    integral;
+               int             s_integral;
+       };
+       unsigned int    fractional;
+} ntp_fp_t;                            /* NTP-compatible time stamp */
+
+#pragma warning(pop)
+
+typedef union pps_timeu {              /* timestamp format */
+       struct timespec tspec;
+       ntp_fp_t        ntpfp;
+       unsigned long   longpad[3];
+} pps_timeu_t;                         /* generic data type to represent time stamps */
+
+/* addition of NTP fixed-point format */
+
+#define NTPFP_M_ADD(r_i, r_f, a_i, a_f)        /* r += a */ \
+       do { \
+               register u_int32 lo_tmp; \
+               register u_int32 hi_tmp; \
+               \
+               lo_tmp = ((r_f) & 0xffff) + ((a_f) & 0xffff); \
+               hi_tmp = (((r_f) >> 16) & 0xffff) + (((a_f) >> 16) & 0xffff); \
+               if (lo_tmp & 0x10000) \
+                       hi_tmp++; \
+               (r_f) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
+               \
+               (r_i) += (a_i); \
+               if (hi_tmp & 0x10000) \
+                       (r_i)++; \
+       } while (0)
+
+#define        NTPFP_L_ADDS(r, a)      NTPFP_M_ADD((r)->integral, (r)->fractional, \
+                                           (a)->s_integral, (a)->fractional)
+
+
+/*
+ * Timestamp information structure
+ */
+
+typedef struct pps_info {
+       pps_seq_t       assert_sequence;        /* seq. num. of assert event */
+       pps_seq_t       clear_sequence;         /* seq. num. of clear event */
+       pps_timeu_t     assert_tu;              /* time of assert event */
+       pps_timeu_t     clear_tu;               /* time of clear event */
+       int             current_mode;           /* current mode bits */
+} pps_info_t;
+
+#define assert_timestamp       assert_tu.tspec
+#define clear_timestamp        clear_tu.tspec
+
+#define assert_timestamp_ntpfp assert_tu.ntpfp
+#define clear_timestamp_ntpfp  clear_tu.ntpfp
+
+/*
+ * Parameter structure
+ */
+
+typedef struct pps_params {
+       int             api_version;    /* API version # */
+       int             mode;           /* mode bits */
+       pps_timeu_t     assert_off_tu;  /* offset compensation for assert */
+       pps_timeu_t     clear_off_tu;   /* offset compensation for clear */
+} pps_params_t;
+
+#define assert_offset          assert_off_tu.tspec
+#define clear_offset           clear_off_tu.tspec
+
+#define assert_offset_ntpfp    assert_off_tu.ntpfp
+#define clear_offset_ntpfp     clear_off_tu.ntpfp
+
+/*
+ * The following definitions are architecture-dependent
+ */
+
+#define PPS_CAP (PPS_CAPTUREASSERT | PPS_OFFSETASSERT | PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)
+#define PPS_RO (PPS_CANWAIT | PPS_CANPOLL)
+
+typedef struct {
+       int filedes;            /* file descriptor */
+       OVERLAPPED ol;          /* caches ol.hEvent for DeviceIoControl */
+       pps_params_t params;    /* PPS parameters set by user */
+} pps_unit_t;
+
+typedef pps_unit_t* pps_handle_t; /* pps handlebars */
+
+/*
+ *------ Here begins the implementation-specific part! ------
+ */
+
+#include <windows.h>
+#include <errno.h>
+
+#ifndef EOPNOTSUPP
+#define EOPNOTSUPP 45
+#endif
+
+typedef struct _OLD_SERIAL_PPS_STAMPS {
+   LARGE_INTEGER Timestamp;
+   LARGE_INTEGER Counterstamp;
+} OLD_SERIAL_PPS_STAMPS, *POLDSERIAL_PPS_STAMPS;
+
+typedef struct _SERIAL_PPS_STAMPS {
+   LARGE_INTEGER Timestamp;
+   LARGE_INTEGER Counterstamp;
+   DWORD SeqNum;
+} SERIAL_PPS_STAMPS, *PSERIAL_PPS_STAMPS;
+
+#define IOCTL_SERIAL_GET_PPS_STAMPS    CTL_CODE(FILE_DEVICE_SERIAL_PORT,114,METHOD_BUFFERED,FILE_ANY_ACCESS)
+
+/* byte offset of member m in struct typedef s */
+#define PPS_OFFSETOF(m,s)      (size_t)(&((s *)0)->m)
+
+/*
+ * ntpd on Windows only looks to errno after finding
+ * GetLastError returns NO_ERROR.  To accomodate its
+ * use of msyslog in portable code such as refclock_atom.c,
+ * this implementation always clears the Windows
+ * error code using SetLastError(NO_ERROR) when
+ * returning an errno.  This is also a good idea
+ * for any non-ntpd clients as they should use only
+ * the errno for PPSAPI functions.
+ */
+#define        RETURN_PPS_ERRNO(e)     \
+do {   \
+       SetLastError(NO_ERROR); \
+       errno = (e);    \
+       return -1;      \
+} while (0)
+
+
+#ifdef OWN_PPS_NTP_TIMESTAMP_FROM_COUNTER
+extern void pps_ntp_timestamp_from_counter(ntp_fp_t *, ULONGLONG, ULONGLONG);
+#else
+/*
+ * helper routine for serialpps.sys ioctl which returns 
+ * performance counter "timestamp" as well as a system
+ * FILETIME timestamp.  Converts one of the inputs to
+ * NTP fixed-point format.
+ */
+static inline void 
+pps_ntp_timestamp_from_counter(
+       ntp_fp_t        *result, 
+       ULONGLONG       Timestamp, 
+       ULONGLONG       Counterstamp)
+{
+       ULONGLONG BiasedTimestamp;
+
+       /* convert from 100ns units to NTP fixed point format */
+
+       BiasedTimestamp = Timestamp - PPS_FILETIME_1970;
+       result->integral = PPS_JAN_1970 + 
+               (unsigned)(BiasedTimestamp / PPS_HECTONANOSECONDS);
+       result->fractional = 
+               (unsigned) ((BiasedTimestamp % PPS_HECTONANOSECONDS) *
+               (PPS_FRAC / PPS_HECTONANOSECONDS));
+}
+#endif
+
+
+/*
+ * create PPS handle from file descriptor
+ */
+
+static inline int
+time_pps_create(
+       int filedes,            /* file descriptor */
+       pps_handle_t *handle    /* returned handle */
+       )
+{
+       OLD_SERIAL_PPS_STAMPS old_pps_stamps;
+       DWORD bytes;
+       OVERLAPPED ol;
+
+       /*
+        * Check for valid arguments and attach PPS signal.
+        */
+
+       if (!handle)
+               RETURN_PPS_ERRNO(EFAULT);
+
+       if (PPS_OFFSETOF(tspec.tv_nsec, pps_timeu_t) != 
+           PPS_OFFSETOF(ntpfp.fractional, pps_timeu_t)) {
+               fprintf(stderr,
+                       "timepps.h needs work, union of \n"
+                       "unsigned int ntp_fp.integral and\n"
+                       "time_t timespec.tv_sec accessed\n"
+                       "interchangeably.\n");
+               RETURN_PPS_ERRNO(EFAULT);
+       }
+
+       /*
+        * For this ioctl which will never block, we don't want to go
+        * through the overhead of a completion port, so we use an
+        * event handle in the overlapped structure with its 1 bit set.
+        *
+        * From GetQueuedCompletionStatus docs:
+        * Even if you have passed the function a file handle associated 
+        * with a completion port and a valid OVERLAPPED structure, an 
+        * application can prevent completion port notification. This is 
+        * done by specifying a valid event handle for the hEvent member 
+        * of the OVERLAPPED structure, and setting its low-order bit. A 
+        * valid event handle whose low-order bit is set keeps I/O 
+        * completion from being queued to the completion port.
+        */
+
+       ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+       ol.hEvent = (HANDLE) ((ULONG_PTR)ol.hEvent | 1);
+
+       if (FALSE == DeviceIoControl(
+               (HANDLE)_get_osfhandle(filedes), 
+               IOCTL_SERIAL_GET_PPS_STAMPS, 
+               NULL, 
+               0, 
+               &old_pps_stamps, 
+               sizeof(old_pps_stamps), 
+               &bytes, 
+               &ol)
+               || sizeof(old_pps_stamps) != bytes) {
+
+               /* 
+                * If you want to write some dead code this could detect the 
+                * IOCTL being pended, but the driver always has the info
+                * instantly, so ERROR_IO_PENDING isn't a concern.
+                */
+
+               CloseHandle(ol.hEvent);
+               fprintf(stderr,
+                       "time_pps_create: IOCTL_SERIAL_GET_PPS_STAMPS: %d %d\n",
+                       bytes,
+                       GetLastError());
+               RETURN_PPS_ERRNO(ENXIO);
+       }
+
+       /*
+        * Allocate and initialize default unit structure.
+        */
+
+       *handle = malloc(sizeof(pps_unit_t));
+       if (!(*handle))
+               RETURN_PPS_ERRNO(ENOMEM);
+
+       memset(*handle, 0, sizeof(pps_unit_t));
+       (*handle)->filedes = filedes;
+       (*handle)->ol.hEvent = ol.hEvent;
+       (*handle)->params.api_version = PPS_API_VERS_1;
+       (*handle)->params.mode = PPS_CAPTUREASSERT | PPS_TSFMT_TSPEC;
+       return (0);
+}
+
+/*
+ * release PPS handle
+ */
+
+static inline int
+time_pps_destroy(
+       pps_handle_t handle
+       )
+{
+       /*
+        * Check for valid arguments and detach PPS signal.
+        */
+
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       CloseHandle(handle->ol.hEvent);
+       free(handle);
+       return (0);
+}
+
+/*
+ * set parameters for handle
+ */
+
+static inline int
+time_pps_setparams(
+       pps_handle_t handle,
+       const pps_params_t *params
+       )
+{
+       int     mode, mode_in;
+       /*
+        * Check for valid arguments and set parameters.
+        */
+
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       if (!params)
+               RETURN_PPS_ERRNO(EFAULT);
+
+       /*
+        * There was no reasonable consensu in the API working group.
+        * I require `api_version' to be set!
+        */
+
+       if (params->api_version != PPS_API_VERS_1)
+               RETURN_PPS_ERRNO(EINVAL);
+
+       /*
+        * only settable modes are PPS_CAPTUREASSERT and PPS_OFFSETASSERT
+        */
+
+       mode_in = params->mode;
+
+       /*
+        * Only one of the time formats may be selected
+        * if a nonzero assert offset is supplied.
+        */
+       if ((mode_in & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) ==
+           (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) {
+
+               if (handle->params.assert_offset.tv_sec ||
+                   handle->params.assert_offset.tv_nsec) 
+
+                       RETURN_PPS_ERRNO(EINVAL);
+
+               /*
+                * If no offset was specified but both time
+                * format flags are used consider it harmless
+                * but turn off PPS_TSFMT_NTPFP so getparams
+                * will not show both formats lit.
+                */
+               mode_in &= ~PPS_TSFMT_NTPFP;
+       }
+
+       /* turn off read-only bits */
+
+       mode_in &= ~PPS_RO;
+
+       /*
+        * test remaining bits, should only have captureassert, 
+        * offsetassert, and/or timestamp format bits.
+        */
+
+       if (mode_in & ~(PPS_CAPTUREASSERT | PPS_OFFSETASSERT |
+                       PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP))
+               RETURN_PPS_ERRNO(EOPNOTSUPP);
+
+       /*
+        * ok, ready to go.
+        */
+
+       mode = handle->params.mode;
+       handle->params = *params;
+       handle->params.mode = mode | mode_in;
+       handle->params.api_version = PPS_API_VERS_1;
+       return (0);
+}
+
+/*
+ * get parameters for handle
+ */
+
+static inline int
+time_pps_getparams(
+       pps_handle_t handle,
+       pps_params_t *params
+       )
+{
+       /*
+        * Check for valid arguments and get parameters.
+        */
+
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       if (!params)
+               RETURN_PPS_ERRNO(EFAULT);
+
+       *params = handle->params;
+       return (0);
+}
+
+/* (
+ * get capabilities for handle
+ */
+
+static inline int
+time_pps_getcap(
+       pps_handle_t handle,
+       int *mode
+       )
+{
+       /*
+        * Check for valid arguments and get capabilities.
+        */
+
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       if (!mode)
+               RETURN_PPS_ERRNO(EFAULT);
+
+       *mode = PPS_CAP;
+       return (0);
+}
+
+/*
+ * Fetch timestamps
+ */
+
+static inline int
+time_pps_fetch(
+       pps_handle_t handle,
+       const int tsformat,
+       pps_info_t *ppsinfo,
+       const struct timespec *timeout
+       )
+{
+       SERIAL_PPS_STAMPS pps_stamps;
+       pps_info_t infobuf;
+       BOOL rc;
+       DWORD bytes;
+       DWORD lasterr;
+
+       /*
+        * Check for valid arguments and fetch timestamps
+        */
+
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       if (!ppsinfo)
+               RETURN_PPS_ERRNO(EFAULT);
+
+       /*
+        * nb. PPS_CANWAIT is NOT set by the implementation, we can totally
+        * ignore the timeout variable.
+        */
+
+       memset(&infobuf, 0, sizeof(infobuf));
+
+       /*
+        * if not captureassert, nothing to return.
+        */
+
+       if (!handle->params.mode & PPS_CAPTUREASSERT) {
+               *ppsinfo = infobuf;
+               return (0);
+       }
+
+       /*
+        * First rev of serialpps.sys didn't support the SeqNum field,
+        * support it by simply returning constant 0 for serial in that case.
+        */
+       pps_stamps.SeqNum = 0;
+
+       /*
+        * interrogate (hopefully) serialpps.sys
+        * if it's the standard serial.sys or another driver,
+        * IOCTL_SERIAL_GET_PPS_STAMPS is most likely unknown
+        * and will result in ERROR_INVALID_PARAMETER.
+        */
+       bytes = 0;
+
+       rc = DeviceIoControl(
+               (HANDLE)_get_osfhandle(handle->filedes), 
+               IOCTL_SERIAL_GET_PPS_STAMPS, 
+               NULL, 
+               0, 
+               &pps_stamps, 
+               sizeof(pps_stamps), 
+               &bytes, 
+               &handle->ol);
+
+       if (!rc) {
+
+               lasterr = GetLastError();
+               if (ERROR_INVALID_PARAMETER != lasterr) 
+                       fprintf(stderr, "time_pps_fetch: ioctl err %d\n", 
+                                       lasterr);
+               RETURN_PPS_ERRNO(EOPNOTSUPP);
+
+       } else if (bytes != sizeof(pps_stamps) &&
+                  bytes != sizeof(OLD_SERIAL_PPS_STAMPS)) {
+
+               fprintf(stderr, 
+                       "time_pps_fetch: wanted %d or %d bytes got %d from "
+                       "IOCTL_SERIAL_GET_PPS_STAMPS 0x%x\n" ,
+                       sizeof(OLD_SERIAL_PPS_STAMPS),
+                       sizeof(SERIAL_PPS_STAMPS),
+                       bytes,
+                       IOCTL_SERIAL_GET_PPS_STAMPS);
+               RETURN_PPS_ERRNO(ENXIO);
+       }
+
+       /*
+        * pps_ntp_timestamp_from_counter takes the two flavors
+        * of timestamp we have (counter and system time) and
+        * uses whichever it can to give the best NTP fixed-point
+        * conversion.  In ntpd the Counterstamp is typically
+        * used.  A stub implementation in this file simply
+        * converts from Windows Timestamp to NTP fixed-point.
+        */
+       pps_ntp_timestamp_from_counter(
+               &infobuf.assert_timestamp_ntpfp, 
+               pps_stamps.Timestamp.QuadPart, 
+               pps_stamps.Counterstamp.QuadPart);
+
+       /*
+        * Note that only assert timestamps
+        * are captured by this interface.
+        */
+
+       infobuf.assert_sequence = pps_stamps.SeqNum;
+
+       /*
+        * Apply offset and translate to specified format
+        */
+
+       switch (tsformat) {
+       case PPS_TSFMT_NTPFP:   /* NTP format requires no translation */
+               if (handle->params.mode & PPS_OFFSETASSERT) {
+                       NTPFP_L_ADDS(&infobuf.assert_timestamp_ntpfp, 
+                                    &handle->params.assert_offset_ntpfp);
+               }
+               break;          
+
+       case PPS_TSFMT_TSPEC:   /* timespec format requires conversion to nsecs form */
+               PPS_NTPTOTSPEC(infobuf.assert_timestamp);
+               if (handle->params.mode & PPS_OFFSETASSERT) {
+                       infobuf.assert_timestamp.tv_sec  += 
+                               handle->params.assert_offset.tv_sec;
+                       infobuf.assert_timestamp.tv_nsec += 
+                               handle->params.assert_offset.tv_nsec;
+                       PPS_NORMALIZE(infobuf.assert_timestamp);
+               }
+               break;
+
+       default:
+               RETURN_PPS_ERRNO(EINVAL);
+       }
+
+       infobuf.current_mode = handle->params.mode;
+       *ppsinfo = infobuf;
+       return (0);
+}
+
+/*
+ * time_pps_kcbind - specify kernel consumer
+ *
+ * Not supported so far by Windows.
+ */
+
+static inline int
+time_pps_kcbind(
+       pps_handle_t handle,
+       const int kernel_consumer,
+       const int edge, const int tsformat
+       )
+{
+       /*
+        * Check for valid arguments before revealing the ugly truth
+        */
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       RETURN_PPS_ERRNO(EOPNOTSUPP);
+}
+
+
+
+#endif /* _SYS_TIMEPPS_H_ */
diff --git a/ports/winnt/ppsapi/loopback/monolithic-serialpps-timepps.txt b/ports/winnt/ppsapi/loopback/monolithic-serialpps-timepps.txt
new file mode 100644 (file)
index 0000000..ce77865
--- /dev/null
@@ -0,0 +1,52 @@
+/***********************************************************************
+ *                                                                    *
+ * Copyright (c) David L. Mills 1999-2000                             *
+ *                                                                    *
+ * Permission to use, copy, modify, and distribute this software and   *
+ * its documentation for any purpose and without fee is hereby        *
+ * granted, provided that the above copyright notice appears in all    *
+ * copies and that both the copyright notice and this permission       *
+ * notice appear in supporting documentation, and that the name        *
+ * University of Delaware not be used in advertising or publicity      *
+ * pertaining to distribution of the software without specific,        *
+ * written prior permission. The University of Delaware makes no       *
+ * representations about the suitability this software for any        *
+ * purpose. It is provided "as is" without express or implied          *
+ * warranty.                                                          *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * This header file complies with "Pulse-Per-Second API for UNIX-like  *
+ * Operating Systems, Version 1.0", rfc2783. Credit is due Jeff Mogul  *
+ * and Marc Brett, from whom much of this code was shamelessly stolen. *
+ *                                                                    *
+ * This modified timepps.h can be used to provide a PPSAPI interface   *
+ * to a machine running Windows with a suitably modified              *
+ * serialpps.sys being used in place of serial.sys.  It can           *
+ * be extended to support a modified parallel port driver once        *
+ * available.                                                         *
+ *                                                                    *
+ * This Windows version was derived by Dave Hart                      *
+ * <davehart@davehart.com> from Mills' timepps-Solaris.h              *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * Some of this include file                                          *
+ * Copyright (c) 1999 by Ulrich Windl,                                *
+ *     based on code by Reg Clemens <reg@dwf.com>                     *
+ *             based on code by Poul-Henning Kamp <phk@FreeBSD.org>   *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * "THE BEER-WARE LICENSE" (Revision 42):                              *
+ * <phk@FreeBSD.org> wrote this file.  As long as you retain this      *
+ * notice you can do whatever you want with this stuff. If we meet some*
+ * day, and you think this stuff is worth it, you can buy me a beer    *
+ * in return.  Poul-Henning Kamp                                      *
+ *                                                                    *
+ **********************************************************************/
+
+timepps.h implements IETF RFC "Pulse-Per-Second API for UNIX-like 
+Operating Systems, Version 1.0" for Microsoft Windows.
+
+
diff --git a/ports/winnt/ppsapi/loopback/src/loopback-ppsapi.c b/ports/winnt/ppsapi/loopback/src/loopback-ppsapi.c
new file mode 100644 (file)
index 0000000..4a708f4
--- /dev/null
@@ -0,0 +1,465 @@
+/*
+ * loopback-ppsapi-provider.c - derived from monolithic timepps.h
+ *                              for usermode PPS by Juergen Perlinger
+ */
+
+/***********************************************************************
+ *                                                                    *
+ * Copyright (c) David L. Mills 1999-2009                             *
+ *                                                                    *
+ * Permission to use, copy, modify, and distribute this software and   *
+ * its documentation for any purpose and without fee is hereby        *
+ * granted, provided that the above copyright notice appears in all    *
+ * copies and that both the copyright notice and this permission       *
+ * notice appear in supporting documentation, and that the name        *
+ * University of Delaware not be used in advertising or publicity      *
+ * pertaining to distribution of the software without specific,        *
+ * written prior permission. The University of Delaware makes no       *
+ * representations about the suitability this software for any        *
+ * purpose. It is provided "as is" without express or implied          *
+ * warranty.                                                          *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * This header file complies with "Pulse-Per-Second API for UNIX-like  *
+ * Operating Systems, Version 1.0", rfc2783. Credit is due Jeff Mogul  *
+ * and Marc Brett, from whom much of this code was shamelessly stolen. *
+ *                                                                    *
+ * This serialpps-ppsapi-provider.dll implements the PPSAPI provider   *
+ * for serialpps.sys, which is a very lightly patched Windows         *
+ * serial.sys with CD timestamping support.
+ *                                                                    *
+ * This Windows version was derived by Dave Hart                      *
+ * <davehart@davehart.com> from David L. Mills' timepps-Solaris.h      *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * Some of this include file                                          *
+ * Copyright (c) 1999 by Ulrich Windl,                                *
+ *     based on code by Reg Clemens <reg@dwf.com>                     *
+ *             based on code by Poul-Henning Kamp <phk@FreeBSD.org>   *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * "THE BEER-WARE LICENSE" (Revision 42):                             *
+ * <phk@FreeBSD.org> wrote this file.  As long as you retain this      *
+ * notice you can do whatever you want with this stuff. If we meet some*
+ * day, and you think this stuff is worth it, you can buy me a beer    *
+ * in return.  Poul-Henning Kamp                                      *
+ *                                                                    *
+ **********************************************************************/
+
+/*
+ * Implementation note: the logical states ``assert'' and ``clear''
+ * are implemented in terms of the UART register, i.e. ``assert''
+ * means the bit is set. This follows the sense of the serial driver
+ * of the Windows OS, and is opposite of the RS-232 spec for the
+ * CD/DCD logical state.
+ */
+
+
+#define PPSAPI_PROVIDER_EXPORTS
+#include "loopback-ppsapi.h"
+
+/*
+** global stuff
+*/
+
+pcreate_pps_handle p_create_pps_handle;
+
+#define SERIALPPS_CAPS (PPS_CAPTUREBOTH | PPS_OFFSETBOTH | PPS_TSFMT_BOTH)
+#define SERIALPPS_RO   (PPS_CANWAIT | PPS_CANPOLL)
+
+
+/*
+ * The ntp_timestamp_from_counter callback into timepps.h routines in
+ * the host is saved in each unit separately, so that binaries that
+ * inline timepps.h into multiple source files (such as refclock_atom.c
+ * and a number of other ntpd refclocks including refclock_nmea.c) will
+ * get called back in the correct instance for each unit.  This assumes 
+ * that ppsapi_prov_init for subsequent instances happens only after the
+ * first instance has completed all time_pps_create() calls it will
+ * invoke, which is a safe assumption at least for ntpd.
+ */
+struct loopback_unit {
+       HANDLE          hnd_dev;        /* true device handle   */
+       HANDLE          hnd_pps;        /* loopback handle      */
+       ntp_fp_t        ofs_assert;     /* correction for assert*/
+       ntp_fp_t        ofs_clear;      /* correction for clear */
+};
+typedef struct loopback_unit loopback_unit;
+
+/*
+ * --------------------------------------------------------------------
+ * DllMain - DLL entrypoint, no-op.
+ * --------------------------------------------------------------------
+ */
+BOOL APIENTRY DllMain(
+       HMODULE hModule,
+       DWORD   why,
+       LPVOID  lpReserved
+       )
+{
+       UNUSED(hModule);
+       UNUSED(lpReserved);
+       UNUSED(why);
+
+       return TRUE;
+}
+
+/*
+ * --------------------------------------------------------------------
+ * time conversion and other helpers
+ * --------------------------------------------------------------------
+ */
+
+/* --------------------------------------------------------------------
+ * convert fixed point time stamp to struct timespec, with proper
+ * Epoch/Era unfolding around the current time.
+ */
+static struct timespec
+fp_stamp_to_tspec(
+       ntp_fp_t        x,
+       time_t          p
+       )
+{
+       struct timespec out;
+       u_int64         tmp;
+       u_int32         ntp;
+
+       ntp  = x.I.u;
+       tmp  = p;
+       tmp -= 0x80000000u;             /* unshift of half range */
+       ntp -= (u_int32)PPS_JAN_1970;   /* warp into UN*X domain */
+       ntp -= (u_int32)tmp;            /* cycle difference      */
+       tmp += (u_int64)ntp;            /* get expanded time     */
+       out.tv_sec  = (time_t)tmp;
+       out.tv_nsec = ((long)(((u_int64)x.F.u * PPS_NANOSECOND + 0x80000000u) >> 32));
+       if (out.tv_nsec >= PPS_NANOSECOND) {
+               out.tv_nsec -= PPS_NANOSECOND;
+               out.tv_sec++;
+       }
+       
+       return out;
+}
+
+/* --------------------------------------------------------------------
+ * convert a duration in struct timespec format to
+ * fixed point representation.
+ */
+static ntp_fp_t
+tspec_to_fp(
+           const struct timespec *     ts
+           )
+{
+       ntp_fp_t        out;
+       long            tmp;
+
+       out.I.u = (u_int32)ts->tv_sec;
+       tmp     = ts->tv_nsec;
+       if (tmp < 0)
+               do {
+                       tmp += PPS_NANOSECOND;
+                       out.I.u--;
+               } while (tmp < 0);
+       else if (tmp >= PPS_NANOSECOND)
+               do {
+                       tmp -= PPS_NANOSECOND;
+                       out.I.u++;
+               } while (tmp >= PPS_NANOSECOND);
+       out.F.u = (u_int32)((u_int64)tmp << 32) + (PPS_NANOSECOND / 2) / PPS_NANOSECOND;
+       return out;
+}
+
+/* --------------------------------------------------------------------
+ * count number of '1' bits in a u_long
+ */
+static size_t
+popcount(
+       u_long  val
+       )
+{
+       size_t  res;
+
+       for (res = 0; val; res++)
+               val &= (val - 1);
+       return res;
+}
+
+/*
+ * --------------------------------------------------------------------
+ * API function implementation
+ * --------------------------------------------------------------------
+ */
+
+/* --------------------------------------------------------------------
+ * prov_time_pps_create - create PPS handle given underlying device
+ */
+int WINAPI
+prov_time_pps_create(
+       HANDLE          device, /* underlying device */
+       pps_handle_t *  handle  /* returned handle */
+       )
+{
+       loopback_unit * loopunit;
+       pps_unit_t *    punit;
+
+       /*
+        * Allocate and initialize loopback unit structure.
+        */
+       loopunit = (loopback_unit*)calloc(1, sizeof(loopback_unit));
+       if (NULL == loopunit)
+               return ENOMEM;
+
+       /* Try to attach to NTPD internal data with the device handle.
+        * Free unit buffer on failure.
+        */
+       loopunit->hnd_dev = device;
+       loopunit->hnd_pps = ntp_pps_attach_device(device);
+       if (NULL == loopunit->hnd_pps) {
+               free(loopunit);
+               return ENXIO;
+       }
+
+       /* create the outer PPS handle structure. Undo work done so far
+        * if things go wrong.
+        */
+       *handle = (*p_create_pps_handle)(loopunit);
+       if (!*handle) {
+               ntp_pps_detach_device(loopunit->hnd_pps);
+               free(loopunit);
+               return ENOMEM;
+       }
+
+       /* All good so far. Store things to remember. */
+       punit = (pps_unit_t *)*handle;
+       punit->params.api_version = PPS_API_VERS_1;
+       punit->params.mode = PPS_CAPTUREBOTH | PPS_TSFMT_BOTH;
+       return 0;
+}
+
+
+/* --------------------------------------------------------------------
+ * prov_time_pps_destroy - release PPS handle
+ */
+int WINAPI
+prov_time_pps_destroy(
+       pps_unit_t *    unit,
+       void *          context
+       )
+{
+       loopback_unit * loopunit;
+
+       loopunit = (loopback_unit*)context;
+       if (unit->context == context)
+               unit->context = NULL;
+       if (NULL != loopunit)
+               ntp_pps_detach_device(loopunit->hnd_pps);
+       free(loopunit);
+       return 0;
+}
+
+
+/* --------------------------------------------------------------------
+ * prov_time_pps_setparams - set parameters for handle
+ */
+int WINAPI
+prov_time_pps_setparams(
+       pps_unit_t *            unit,
+       void *                  context,
+       const pps_params_t *    params
+       )
+{
+       loopback_unit * loopunit;
+       int             mode;
+
+       loopunit = (loopback_unit*)context;
+       mode     = params->mode;
+
+       /*
+        * There was no reasonable consensus in the API working group.
+        * I require `api_version' to be set!
+        */
+       if (params->api_version != PPS_API_VERS_1)
+               return EINVAL;
+
+       /*
+        * We support all edges and formats plus offsets, but not
+        * POLL or WAIT. And we are strict on the time stamp format:
+        * Only one is permitted if we set offsets!
+        */
+
+       /*
+        * Only one of the time formats may be selected.
+        */
+       if ((mode & PPS_OFFSETBOTH)         != 0 &&
+           popcount(mode & PPS_TSFMT_BOTH) != 1  )
+               return EINVAL;
+
+       /* turn off read-only bits */
+       mode &= ~SERIALPPS_RO;
+
+       /*
+        * test remaining bits.
+        */
+       if (mode & ~(PPS_CAPTUREBOTH | PPS_OFFSETBOTH | PPS_TSFMT_BOTH))
+               return EOPNOTSUPP;
+
+       /*
+        * ok, ready to go.
+        *
+        * calculate offsets as ntp_fp_t's and store them in unit as ntp_fp_t. They will
+        * be always applied, since fetching the time stamps is not critical.
+        */
+       if (mode & PPS_OFFSETASSERT) {
+               if (mode & PPS_TSFMT_TSPEC)
+                       loopunit->ofs_assert = tspec_to_fp(&params->assert_offset);
+               else
+                       loopunit->ofs_assert = params->assert_offset_ntpfp;
+       }
+       if (mode & PPS_OFFSETCLEAR) {
+               if (mode & PPS_TSFMT_TSPEC)
+                       loopunit->ofs_clear = tspec_to_fp(&params->clear_offset);
+               else
+                       loopunit->ofs_clear = params->clear_offset_ntpfp;
+       }
+       /* save remaining bits */
+       mode |= unit->params.mode;
+       unit->params = *params;
+       unit->params.mode = mode;
+
+       return 0;
+}
+
+
+/* --------------------------------------------------------------------
+ * prov_time_pps_fetch - Fetch timestamps
+ */
+
+int WINAPI
+prov_time_pps_fetch(
+       pps_unit_t *            unit,
+       void *                  context,
+       const int               tsformat,
+       pps_info_t *            pinfo,
+       const struct timespec * timeout
+       )
+{
+       loopback_unit *         loopunit;
+       PPSData_t               pps_stamps;
+       pps_info_t              infobuf;
+       BOOL                    rc;
+       time_t                  tnow;
+
+       /*
+        * nb. PPS_CANWAIT is NOT set by the implementation, we can totally
+        * ignore the timeout variable.
+        */
+       UNUSED(timeout);
+       loopunit = (loopback_unit*)context;
+
+       /* read & check raw data from daemon */
+       memset(&infobuf, 0, sizeof(infobuf));
+       rc = ntp_pps_read(loopunit->hnd_pps, &pps_stamps, sizeof(pps_stamps));
+       if (!rc) {
+               switch (GetLastError())
+               {
+               case ERROR_INVALID_HANDLE:
+                       return EINVAL;
+               case ERROR_INVALID_PARAMETER:
+                       return EOPNOTSUPP;
+               case ERROR_INVALID_DATA:
+                       return ENXIO;
+               default:
+                       return EINVAL;
+               }
+       }
+
+       /* add offsets on raw data */
+       NTPFP_L_ADDS(&pps_stamps.ts_assert, &loopunit->ofs_assert);
+       NTPFP_L_ADDS(&pps_stamps.ts_clear , &loopunit->ofs_clear);
+
+       /* store sequence numbers */
+       infobuf.assert_sequence = pps_stamps.cc_assert;
+       infobuf.clear_sequence  = pps_stamps.cc_clear;
+
+       /*
+        * Translate or copy to specified format
+        */
+       switch (tsformat) {
+       case PPS_TSFMT_NTPFP:   /* NTP format requires no translation */
+               infobuf.assert_timestamp_ntpfp = pps_stamps.ts_assert;
+               infobuf.clear_timestamp_ntpfp  = pps_stamps.ts_clear;
+               break;          
+
+       case PPS_TSFMT_TSPEC:   /* timespec format requires conversion to nsecs form */
+               time(&tnow);
+               infobuf.assert_timestamp = fp_stamp_to_tspec(pps_stamps.ts_assert, tnow);
+               infobuf.clear_timestamp  = fp_stamp_to_tspec(pps_stamps.ts_clear, tnow);
+               break;
+
+       default:
+               return EINVAL;
+       }
+
+       infobuf.current_mode = unit->params.mode;
+       *pinfo = infobuf;
+
+       return 0;
+}
+
+
+/* --------------------------------------------------------------------
+ * prov_time_pps_kcbind - specify kernel consumer
+ *
+ * Not supported so far by Windows.
+ */
+int WINAPI
+prov_time_pps_kcbind(
+       pps_unit_t *    punit,
+       void *          context,
+       const int       kernel_consumer,
+       const int       edge,
+       const int       tsformat
+       )
+{
+       UNUSED(punit);
+       UNUSED(context);
+       UNUSED(kernel_consumer);
+       UNUSED(edge);
+       UNUSED(tsformat);
+
+       return EOPNOTSUPP;
+}
+
+
+/* --------------------------------------------------------------------
+ * prov_init - returns capabilities and provider name
+ */
+int WINAPI
+ppsapi_prov_init(
+       int                             ppsapi_timepps_prov_ver,
+       pcreate_pps_handle              create_pps_handle,
+       ppps_ntp_timestamp_from_counter ntp_timestamp_from_counter,
+       char *                          short_name_buf,
+       size_t                          short_name_size,
+       char *                          full_name_buf,
+       size_t                          full_name_size
+       )
+{
+       UNUSED(ntp_timestamp_from_counter);
+
+       if (ppsapi_timepps_prov_ver < PPSAPI_TIMEPPS_PROV_VER)
+               return 0;
+
+       p_create_pps_handle = create_pps_handle;
+
+       strncpy(short_name_buf, "loopback", short_name_size);
+       short_name_buf[short_name_size - 1] ='\0'; /* ensure ASCIIZ */
+       strncpy(full_name_buf, 
+               "loopback user mode DCD change detection",
+               full_name_size);
+       full_name_buf[full_name_size - 1] ='\0'; /* ensure ASCIIZ */
+
+       return SERIALPPS_CAPS;
+}
diff --git a/ports/winnt/ppsapi/loopback/src/loopback-ppsapi.def b/ports/winnt/ppsapi/loopback/src/loopback-ppsapi.def
new file mode 100644 (file)
index 0000000..14573a2
--- /dev/null
@@ -0,0 +1,9 @@
+LIBRARY        "loopback-ppsapi-provider.dll"
+
+EXPORTS
+    ppsapi_prov_init
+    prov_time_pps_create
+    prov_time_pps_destroy
+    prov_time_pps_fetch
+    prov_time_pps_kcbind
+    prov_time_pps_setparams
\ No newline at end of file
diff --git a/ports/winnt/ppsapi/loopback/src/loopback-ppsapi.h b/ports/winnt/ppsapi/loopback/src/loopback-ppsapi.h
new file mode 100644 (file)
index 0000000..5541e33
--- /dev/null
@@ -0,0 +1,49 @@
+//
+// serialpps-ppsapi-provider.h
+//
+// For this tiny project the single header serves as a precompiled header
+// as well, meaning all the bulky headers are included before or within it.
+// Within, in this case.
+//
+
+#define _CRT_SECURE_NO_WARNINGS
+#include <stdio.h>
+#include <windows.h>
+typedef          __int32 int32;
+typedef unsigned __int32 u_int32;
+typedef          __int64 int64;
+typedef unsigned __int64 u_int64;
+#include "timepps.h"
+
+#ifndef UNUSED
+#define UNUSED(item)   ((void)(item))
+#endif
+
+/* PPS data structure as captured by the serial line I/O system. This
+ * must match the local definition in 'ntp_iocompletionport.c' or
+ * 'Bad Things (tm)' are bound to happen.
+ */
+struct PpsData {
+       u_long          cc_assert;
+       u_long          cc_clear;
+       ntp_fp_t        ts_assert;
+       ntp_fp_t        ts_clear;
+};
+typedef struct PpsData PPSData_t;
+
+/* prototypes imported from the NTPD executable */
+__declspec(dllimport) HANDLE WINAPI ntp_pps_attach_device(HANDLE hndIo);
+__declspec(dllimport) void   WINAPI ntp_pps_detach_device(HANDLE ppsHandle);
+__declspec(dllimport) BOOL   WINAPI ntp_pps_read(HANDLE ppsHandle, void*, size_t);
+
+/* prototypes exported to the NTPD executable */
+__declspec(dllexport) int WINAPI prov_time_pps_create(HANDLE, pps_handle_t*);
+__declspec(dllexport) int WINAPI prov_time_pps_destroy(pps_unit_t*, void*);
+__declspec(dllexport) int WINAPI prov_time_pps_setparams(pps_unit_t*, void*,
+                                       const pps_params_t*);
+__declspec(dllexport) int WINAPI prov_time_pps_fetch(pps_unit_t*, void*,
+                                       const int, pps_info_t*, const struct timespec*);
+__declspec(dllexport) int WINAPI prov_time_pps_kcbind(pps_unit_t*, void*, const int, const int, const int);
+__declspec(dllexport) int WINAPI ppsapi_prov_init(int, pcreate_pps_handle,
+                                       ppps_ntp_timestamp_from_counter, char*, size_t,
+                                       char*, size_t);
diff --git a/ports/winnt/ppsapi/loopback/src/sys/time.h b/ports/winnt/ppsapi/loopback/src/sys/time.h
new file mode 100644 (file)
index 0000000..079e5b6
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * This sys/time.h is part of ppsapi-prov skeleton sample source code
+ * for a Windows PPSAPI provider DLL.  It was adapted from
+ * ports/winnt/include/sys/time.h in ntpd.
+ */
+
+#ifndef SYS_TIME_H
+#define SYS_TIME_H
+
+#include <windows.h>
+#include <time.h>
+
+typedef struct timespec {
+       time_t  tv_sec;
+       long    tv_nsec;
+} timespec_t;
+
+#endif /* SYS_TIME_H */
diff --git a/ports/winnt/ppsapi/loopback/src/timepps.h b/ports/winnt/ppsapi/loopback/src/timepps.h
new file mode 100644 (file)
index 0000000..fb1f40c
--- /dev/null
@@ -0,0 +1,805 @@
+/***********************************************************************
+ *                                                                    *
+ * Copyright (c) David L. Mills 1999-2009                             *
+ *                                                                    *
+ * Permission to use, copy, modify, and distribute this software and   *
+ * its documentation for any purpose and without fee is hereby        *
+ * granted, provided that the above copyright notice appears in all    *
+ * copies and that both the copyright notice and this permission       *
+ * notice appear in supporting documentation, and that the name        *
+ * University of Delaware not be used in advertising or publicity      *
+ * pertaining to distribution of the software without specific,        *
+ * written prior permission. The University of Delaware makes no       *
+ * representations about the suitability this software for any        *
+ * purpose. It is provided "as is" without express or implied          *
+ * warranty.                                                          *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * This header file complies with "Pulse-Per-Second API for UNIX-like  *
+ * Operating Systems, Version 1.0", rfc2783. Credit is due Jeff Mogul  *
+ * and Marc Brett, from whom much of this code was shamelessly stolen. *
+ *                                                                    *
+ * This modified timepps.h can be used to provide a PPSAPI interface   *
+ * to a machine running Windows with one or more backend provider DLLs *
+ * implementing the provider interfaces defined herein.                       *
+ *                                                                    *
+ * This Windows version was derived by Dave Hart                      *
+ * <davehart@davehart.com> from Mills' timepps-Solaris.h              *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * Some of this include file                                          *
+ * Copyright (c) 1999 by Ulrich Windl,                                *
+ *     based on code by Reg Clemens <reg@dwf.com>                     *
+ *             based on code by Poul-Henning Kamp <phk@FreeBSD.org>   *
+ *                                                                    *
+ ***********************************************************************
+ *                                                                    *
+ * "THE BEER-WARE LICENSE" (Revision 42):                             *
+ * <phk@FreeBSD.org> wrote this file.  As long as you retain this      *
+ * notice you can do whatever you want with this stuff. If we meet some*
+ * day, and you think this stuff is worth it, you can buy me a beer    *
+ * in return.  Poul-Henning Kamp                                      *
+ *                                                                    *
+ **********************************************************************/
+
+#ifndef TIMEPPS_H
+#define TIMEPPS_H
+
+#include "sys/time.h"  /* in ntp ref source declares struct timespec */
+
+/*
+ * The following definitions are architecture independent
+ */
+
+#define PPS_API_VERS_1         1               /* API version number */
+#define PPS_JAN_1970           2208988800UL    /* 1970 - 1900 in seconds */
+#define PPS_NANOSECOND         1000000000L     /* one nanosecond in decimal */
+#define PPS_FRAC               4294967296.     /* 2^32 as a double */
+#define PPS_HECTONANOSECONDS   10000000        /* 100ns units in a second */
+#define PPS_FILETIME_1970      0x019db1ded53e8000 /* unix epoch to Windows */
+
+#define PPS_NORMALIZE(x)       /* normalize timespec */ \
+       do { \
+               while ((x).tv_nsec >= PPS_NANOSECOND) { \
+                       (x).tv_nsec -= PPS_NANOSECOND; \
+                       (x).tv_sec++; \
+               } \
+               while ((x).tv_nsec < 0) { \
+                       (x).tv_nsec += PPS_NANOSECOND; \
+                       (x).tv_sec--; \
+               } \
+       } while (0)
+
+#define PPS_TSPECTONTP(x)      /* convert timespec to ntp_fp */        \
+       do {                                                            \
+               double d_frac;                                          \
+                                                                       \
+               d_frac = ((struct timespec)&(x))->tv_nsec               \
+                        * PPS_FRAC / PPS_NANOSECOND;                   \
+               (x).integral = ((struct timespec)&(x))->tv_sec          \
+                               + PPS_JAN_1970;                         \
+               (x).fractional = (unsigned int)d_frac;                  \
+               if (d_frac >= PPS_FRAC)                                 \
+                       (x).integral++;                                 \
+       } while (0)
+
+#define PPS_NTPTOTSPEC(x)      /* convert ntp_fp to timespec */        \
+       do {                                                            \
+               double d_frac;                                          \
+                                                                       \
+               /* careful, doing in place and tv_sec may be 64bit */   \
+               d_frac = (double)((ntp_fp_t *)&(x))->F.u                \
+                       * PPS_NANOSECOND / PPS_FRAC;                    \
+               (x).tv_sec = ((ntp_fp_t *)&(x))->I.u                    \
+                            - (time_t)PPS_JAN_1970;                    \
+               (x).tv_nsec = (long)d_frac;                             \
+       } while (0) 
+
+
+/*
+ * Device/implementation parameters (mode)
+ */
+
+#define PPS_CAPTUREASSERT      0x01    /* capture assert events */
+#define PPS_CAPTURECLEAR       0x02    /* capture clear events */
+#define PPS_CAPTUREBOTH        0x03    /* capture assert and clear events */
+
+#define PPS_OFFSETASSERT       0x10    /* apply compensation for assert ev. */
+#define PPS_OFFSETCLEAR        0x20    /* apply compensation for clear ev. */
+#define PPS_OFFSETBOTH         0x30    /* apply compensation for both */
+
+#define PPS_CANWAIT            0x100   /* Can we wait for an event? */
+#define PPS_CANPOLL            0x200   /* "This bit is reserved for */
+
+/*
+ * Kernel actions (mode)
+ */
+
+#define PPS_ECHOASSERT         0x40    /* feed back assert event to output */
+#define PPS_ECHOCLEAR          0x80    /* feed back clear event to output */
+
+/*
+ * Timestamp formats (tsformat)
+ */
+
+#define PPS_TSFMT_TSPEC                0x1000  /* select timespec format */
+#define PPS_TSFMT_NTPFP                0x2000  /* select NTP format */
+#define PPS_TSFMT_BOTH         (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)
+
+/*
+ * Kernel discipline actions (not used in Windows yet)
+ */
+
+#define PPS_KC_HARDPPS         0       /* enable kernel consumer */
+#define PPS_KC_HARDPPS_PLL     1       /* phase-lock mode */
+#define PPS_KC_HARDPPS_FLL     2       /* frequency-lock mode */
+
+/*
+ * Type definitions
+ */
+
+typedef unsigned long pps_seq_t;       /* sequence number */
+
+#pragma warning(push)
+//#pragma warning(disable: 201)                /* nonstd extension nameless union */
+
+typedef struct ntp_fp {
+       union {
+               int32   s;
+               u_int32 u;
+       } I;
+       union {
+               int32   s;
+               u_int32 u;
+       } F;
+} ntp_fp_t;                            /* NTP-compatible time stamp */
+
+#pragma warning(pop)
+
+typedef union pps_timeu {              /* timestamp format */
+       struct timespec tspec;
+       ntp_fp_t        ntpfp;
+       unsigned long   longpad[3];
+} pps_timeu_t;                         /* generic data type to represent time stamps */
+
+/* addition of NTP fixed-point format */
+
+#define NTPFP_M_ADD(r_i, r_f, a_i, a_f)        /* r += a */ \
+       do { \
+               r_f = (u_int32)(r_f) + (u_int32)(a_f); \
+               r_i = (u_int32)(r_i) + (u_int32)(a_i) + \
+                     ((u_int32)(r_f) < (u_int32)(a_f)); \
+       } while (0)
+
+#define        NTPFP_L_ADDS(r, a)      NTPFP_M_ADD((r)->I.u, (r)->F.u, (a)->I.u, (a)->F.u)
+
+
+/*
+ * Timestamp information structure
+ */
+
+typedef struct pps_info {
+       pps_seq_t       assert_sequence;        /* seq. num. of assert event */
+       pps_seq_t       clear_sequence;         /* seq. num. of clear event */
+       pps_timeu_t     assert_tu;              /* time of assert event */
+       pps_timeu_t     clear_tu;               /* time of clear event */
+       int             current_mode;           /* current mode bits */
+} pps_info_t;
+
+#define assert_timestamp       assert_tu.tspec
+#define clear_timestamp        clear_tu.tspec
+
+#define assert_timestamp_ntpfp assert_tu.ntpfp
+#define clear_timestamp_ntpfp  clear_tu.ntpfp
+
+/*
+ * Parameter structure
+ */
+
+typedef struct pps_params {
+       int             api_version;    /* API version # */
+       int             mode;           /* mode bits */
+       pps_timeu_t     assert_off_tu;  /* offset compensation for assert */
+       pps_timeu_t     clear_off_tu;   /* offset compensation for clear */
+} pps_params_t;
+
+#define assert_offset          assert_off_tu.tspec
+#define clear_offset           clear_off_tu.tspec
+
+#define assert_offset_ntpfp    assert_off_tu.ntpfp
+#define clear_offset_ntpfp     clear_off_tu.ntpfp
+
+/*
+ *------ Here begins the implementation-specific part! ------
+ */
+
+#include <windows.h>
+#include <errno.h>
+#include <stddef.h>    /* offsetof() */
+#include <io.h>                /* _get_osfhandle() */
+
+#ifndef EOPNOTSUPP
+#define EOPNOTSUPP 45
+#endif
+
+typedef UINT_PTR pps_handle_t; /* pps handlebars */
+
+#ifndef inline
+#define inline __inline
+#endif
+
+/*
+ * ntpd on Windows is typically distributed as a binary as few users
+ * have the tools needed to build from source.  Rather than build
+ * a single timepps.h for Windows which knows how to talk to all
+ * PPS implementations frozen in time as of compiling, this timepps.h
+ * allows one or more backend providers to be used by naming a DLL
+ * which exports the provider interfaces defined here.
+ */
+typedef enum ppsapi_magic_tag {
+       PPSAPI_MAGIC_UNIT = 0x70707355, /* ppsU */
+} ppsapi_magic;
+
+typedef struct {
+       struct pps_provider_tag *provider;
+       void *          context;/* provider's unit pointer */
+       ppsapi_magic    magic;  /* to detect invalid handles */
+       pps_params_t    params; /* PPS parameters set by user */
+} pps_unit_t;
+
+typedef void (*ppps_ntp_timestamp_from_counter)(
+       ntp_fp_t        *result, 
+       ULONGLONG       Timestamp, 
+       ULONGLONG       Counterstamp
+       );
+
+typedef pps_handle_t (*pcreate_pps_handle)(
+       void *  prov_context
+       );
+
+/*
+ * ppsapi_prov_init() - exported by backend DLLs
+ *
+ * Return value is pps capabilities available to PPSAPI consumers
+ * via time_pps_getcaps().
+ */
+#define PPSAPI_TIMEPPS_PROV_VER                2
+
+typedef int (WINAPI *pppsapi_prov_init)(
+       int     ppsapi_timepps_prov_ver,
+       pcreate_pps_handle      create_pps_handle,
+       ppps_ntp_timestamp_from_counter ntp_timestamp_from_counter,
+       char *  short_name_buf,
+       size_t  short_name_size,
+       char *  full_name_buf,
+       size_t  full_name_size
+       );
+
+typedef int (WINAPI *provtime_pps_create)(
+       HANDLE winhandle,       /* user device handle */
+       pps_handle_t *phandle   /* returned handle */
+       );
+
+typedef int (WINAPI *provtime_pps_destroy)(
+       pps_unit_t *    unit,
+       void *          context
+       );
+
+typedef int (WINAPI *provtime_pps_setparams)(
+       pps_unit_t *            unit,
+       void *                  context,
+       const pps_params_t *    params
+       );
+
+typedef int (WINAPI *provtime_pps_fetch)(
+       pps_unit_t *            unit,
+       void *                  context,
+       const int               tsformat,
+       pps_info_t *            pinfo,
+       const struct timespec * timeout
+       );
+
+typedef int (WINAPI *provtime_pps_kcbind)(
+       pps_unit_t *    unit,
+       void *          context,
+       const int       kernel_consumer,
+       const int       edge, 
+       const int       tsformat
+       );
+
+typedef struct pps_provider_tag {
+       struct pps_provider_tag *next;
+       int                     caps;
+       char *                  short_name;
+       char *                  full_name;
+       provtime_pps_create     ptime_pps_create;
+       provtime_pps_destroy    ptime_pps_destroy;
+       provtime_pps_setparams  ptime_pps_setparams;
+       provtime_pps_fetch      ptime_pps_fetch;
+       provtime_pps_kcbind     ptime_pps_kcbind;
+} ppsapi_provider;
+
+static ppsapi_provider *       g_provider_list;
+static ppsapi_provider *       g_curr_provider;
+
+
+static inline pps_handle_t
+internal_create_pps_handle(
+       void *  prov_context
+       )
+{
+       pps_unit_t *    punit;
+
+       if (NULL == g_curr_provider) {
+               fprintf(stderr, "create_pps_handle: provider backend called me outside time_pps_create\n");
+               punit = NULL;
+       }       else
+               punit = malloc(sizeof(*punit));
+       if (punit != NULL) {
+               punit->provider = g_curr_provider;
+               punit->context = prov_context;
+               punit->magic = PPSAPI_MAGIC_UNIT;
+               memset(&punit->params, 0, sizeof(punit->params));
+       }
+       return (pps_handle_t)punit;
+}
+
+static inline pps_unit_t *
+unit_from_ppsapi_handle(
+       pps_handle_t    handle
+       )
+{
+       pps_unit_t *punit;
+
+       punit = (pps_unit_t *)handle;
+       if (PPSAPI_MAGIC_UNIT != punit->magic)
+               punit = NULL;
+       return punit;
+}
+
+/*
+ * ntpd on Windows only looks to errno after finding
+ * GetLastError returns NO_ERROR.  To accomodate its
+ * use of msyslog in portable code such as refclock_atom.c,
+ * this implementation always clears the Windows
+ * error code using SetLastError(NO_ERROR) when
+ * returning an errno.  This is also a good idea
+ * for any non-ntpd clients as they should rely only
+ * the errno for PPSAPI functions.
+ */
+#define        RETURN_PPS_ERRNO(e)     \
+do {                           \
+       SetLastError(NO_ERROR); \
+       errno = (e);            \
+       return -1;              \
+} while (0)
+
+
+#ifdef OWN_PPS_NTP_TIMESTAMP_FROM_COUNTER
+extern void pps_ntp_timestamp_from_counter(ntp_fp_t *, ULONGLONG, ULONGLONG);
+#else
+/*
+ * helper routine for serialpps.sys ioctl which returns 
+ * performance counter "timestamp" as well as a system
+ * FILETIME timestamp.  Converts one of the inputs to
+ * NTP fixed-point format.
+ *
+ * You will probably want to supply your own and #define
+ * OWN_PPS_NTP_TIMESTAMP_FROM_COUNTER, as this stub
+ * converts only the low-resolution system timestamp.
+ *
+ * When implementing a provider, use the pointer to this
+ * conversion function supplied to your prov_init(), as
+ * the copy in your DLL will likely be the stub below,
+ * where you want the one provided by the PPSAPI client
+ * such as ntpd.
+ */
+static inline void 
+pps_ntp_timestamp_from_counter(
+       ntp_fp_t        *result, 
+       ULONGLONG       Timestamp, 
+       ULONGLONG       Counterstamp)
+{
+       ULONGLONG BiasedTimestamp;
+
+       /* convert from 100ns units to NTP fixed point format */
+
+       BiasedTimestamp = Timestamp - PPS_FILETIME_1970;
+       result->I.u = PPS_JAN_1970 + 
+               (unsigned)(BiasedTimestamp / PPS_HECTONANOSECONDS);
+       result->F.u = 
+               (unsigned) ((BiasedTimestamp % PPS_HECTONANOSECONDS) *
+               (PPS_FRAC / PPS_HECTONANOSECONDS));
+}
+#endif
+
+
+static inline int
+load_pps_provider(
+       char *  dllpath
+       )
+{
+       char                    short_name[16];
+       char                    full_name[64];
+       ppsapi_provider *       prov;
+       HMODULE                 hmod;
+       pppsapi_prov_init       pprov_init;
+
+       prov = malloc(sizeof(*prov));
+       if (NULL == prov)
+               return ENOMEM;
+
+       hmod = LoadLibrary(dllpath);
+       if (NULL == hmod) {
+               fprintf(stderr, "load_pps_provider: LoadLibrary(%s) error %u\n", dllpath, GetLastError());
+               free(prov);
+               return ENOENT;
+       }
+
+       pprov_init = (pppsapi_prov_init)GetProcAddress(hmod, "ppsapi_prov_init");
+       if (NULL == pprov_init) {
+               fprintf(stderr, "load_pps_provider: entrypoint ppsapi_prov_init not found in %s\n", dllpath);
+               free(prov);
+               FreeLibrary(hmod);
+               return EFAULT;
+       }
+
+       prov->caps = (*pprov_init)(PPSAPI_TIMEPPS_PROV_VER,
+           &internal_create_pps_handle,
+           &pps_ntp_timestamp_from_counter,
+           short_name,  sizeof(short_name),
+           full_name, sizeof(full_name));
+
+       if (!prov->caps) {
+               free(prov);
+               FreeLibrary(hmod);
+               return EACCES;
+       }
+
+       prov->short_name = _strdup(short_name);
+       prov->full_name = _strdup(full_name);
+
+       if (NULL == prov->short_name || !prov->short_name[0]
+           || NULL == prov->full_name || !prov->full_name[0]) {
+
+               if (prov->short_name)
+                       free(prov->short_name);
+               if (prov->full_name)
+                       free(prov->full_name);
+               free(prov);
+               FreeLibrary(hmod);
+               return EINVAL;
+       }
+
+       prov->ptime_pps_create = (provtime_pps_create)
+               GetProcAddress(hmod, "prov_time_pps_create");
+       prov->ptime_pps_destroy = (provtime_pps_destroy)
+               GetProcAddress(hmod, "prov_time_pps_destroy");
+       prov->ptime_pps_setparams = (provtime_pps_setparams)
+               GetProcAddress(hmod, "prov_time_pps_setparams");
+       prov->ptime_pps_fetch = (provtime_pps_fetch)
+               GetProcAddress(hmod, "prov_time_pps_fetch");
+       prov->ptime_pps_kcbind = (provtime_pps_kcbind)
+               GetProcAddress(hmod, "prov_time_pps_kcbind");
+
+       if (NULL == prov->ptime_pps_create
+           || NULL == prov->ptime_pps_destroy
+           || NULL == prov->ptime_pps_setparams
+           || NULL == prov->ptime_pps_fetch
+           || NULL == prov->ptime_pps_kcbind) {
+
+               fprintf(stderr, "PPSAPI provider %s missing entrypoint\n",
+                       prov->short_name);
+               free(prov->short_name);
+               free(prov->full_name);
+               free(prov);
+               FreeLibrary(hmod);
+               return EINVAL;
+       }
+
+       fprintf(stderr, "loaded PPSAPI provider %s caps 0x%x provider %p\n", 
+               prov->full_name, prov->caps, prov);
+
+       prov->next = g_provider_list;
+       g_provider_list = prov;
+
+       return 0;
+}
+
+
+/*
+ * time_pps_create - create PPS handle from file descriptor
+ *
+ * This is the initial entrypoint of PPSAPI from the client.  Note
+ * to maintain source compatibility with Unix, the input file
+ * descriptor really is a descriptor from the C runtime low-numbered
+ * descriptor namespace, though it may have been converted from a
+ * native Windows HANDLE using _open_osfhandle().
+ */
+static inline int
+time_pps_create(
+       int             filedes,/* device file descriptor */
+       pps_handle_t *  phandle /* returned handle */
+       )
+{
+       HANDLE                  winhandle;
+       char *                  dlls;
+       char *                  dll;
+       char *                  pch;
+       ppsapi_provider *       prov;
+       pps_handle_t            ppshandle;
+       int                     err;
+
+       if (NULL == phandle)
+               RETURN_PPS_ERRNO(EFAULT);
+
+       winhandle = (HANDLE)_get_osfhandle(filedes);
+       fprintf(stderr, "time_pps_create(%d) got winhandle %p\n", filedes, winhandle);
+       if (INVALID_HANDLE_VALUE == winhandle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       /*
+        * For initial testing the list of PPSAPI backend
+        * providers is provided by the environment variable
+        * PPSAPI_DLLS, separated by semicolons such as
+        * PPSAPI_DLLS=c:\ntp\serial_ppsapi.dll;..\parport_ppsapi.dll
+        * There are a million better ways, such as a well-known
+        * registry key under which a value is created for each
+        * provider DLL installed, or even a platform-specific
+        * ntp.conf directive or command-line switch.
+        */
+       dlls = getenv("PPSAPI_DLLS");
+       if (dlls != NULL && NULL == g_provider_list) {
+               dlls = dll = _strdup(dlls);
+               fprintf(stderr, "getenv(PPSAPI_DLLS) gives %s\n", dlls);
+       } else
+               dlls = dll = NULL;
+
+       while (dll != NULL && dll[0]) {
+               pch = strchr(dll, ';');
+               if (pch != NULL)
+                       *pch = 0;
+               err = load_pps_provider(dll);
+               if (err) {
+                       fprintf(stderr, "load_pps_provider(%s) got errno %d\n", dll, err);
+                       RETURN_PPS_ERRNO(err);
+               }
+               dll = (NULL == pch)
+                         ? NULL
+                         : pch + 1;
+       }
+
+       if (NULL != dlls)
+               free(dlls);
+       dlls = dll = NULL;
+
+       /*
+        * Hand off to each provider in turn until one returns a PPS
+        * handle or they've all declined.
+        */
+       for (prov = g_provider_list; prov != NULL; prov = prov->next) {
+               ppshandle = 0;
+               g_curr_provider = prov;
+               err = (*prov->ptime_pps_create)(winhandle, &ppshandle);
+               g_curr_provider = NULL;
+               fprintf(stderr, "%s prov_time_pps_create(%p) returned %d\n",
+                       prov->short_name, winhandle, err);
+               if (!err && ppshandle) {
+                       *phandle = ppshandle;
+                       return 0;
+               }
+       }
+
+       fprintf(stderr, "PPSAPI provider list %p\n", g_provider_list);
+
+       RETURN_PPS_ERRNO(ENOEXEC);
+}
+
+
+/*
+ * release PPS handle
+ */
+
+static inline int
+time_pps_destroy(
+       pps_handle_t handle
+       )
+{
+       pps_unit_t *    punit;
+       int err;
+
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       punit = unit_from_ppsapi_handle(handle);
+
+       if (NULL == punit)
+               RETURN_PPS_ERRNO(EBADF);
+
+       err = (*punit->provider->ptime_pps_destroy)(punit, punit->context);
+
+       free(punit);
+
+       if (err)
+               RETURN_PPS_ERRNO(err);
+       else
+               return 0;
+}
+
+/*
+ * set parameters for handle
+ */
+
+static inline int
+time_pps_setparams(
+       pps_handle_t handle,
+       const pps_params_t *params
+       )
+{
+       pps_unit_t *    punit;
+       int             err;
+
+       /*
+        * Check for valid arguments and set parameters.
+        */
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       punit = unit_from_ppsapi_handle(handle);
+
+       if (NULL == punit)
+               RETURN_PPS_ERRNO(EBADF);
+
+       if (NULL == params)
+               RETURN_PPS_ERRNO(EFAULT);
+
+       err = (*punit->provider->ptime_pps_setparams)(punit, punit->context, params);
+
+       if (err)
+               RETURN_PPS_ERRNO(err);
+       else
+               return 0;
+}
+
+/*
+ * get parameters for handle
+ */
+
+static inline int
+time_pps_getparams(
+       pps_handle_t handle,
+       pps_params_t *params_buf
+       )
+{
+       pps_unit_t *    punit;
+
+       /*
+        * Check for valid arguments and get parameters.
+        */
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       punit = unit_from_ppsapi_handle(handle);
+
+       if (NULL == punit)
+               RETURN_PPS_ERRNO(EBADF);
+
+       if (NULL == params_buf)
+               RETURN_PPS_ERRNO(EFAULT);
+
+       *params_buf = punit->params;
+       return 0;
+}
+
+
+/* 
+ * time_pps_getcap - get capabilities for handle
+ */
+static inline int
+time_pps_getcap(
+       pps_handle_t handle,
+       int *pmode
+       )
+{
+       pps_unit_t *    punit;
+
+       /*
+        * Check for valid arguments and get capabilities.
+        */
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       punit = unit_from_ppsapi_handle(handle);
+
+       if (NULL == punit)
+               RETURN_PPS_ERRNO(EBADF);
+
+       if (NULL == pmode)
+               RETURN_PPS_ERRNO(EFAULT);
+
+       *pmode = punit->provider->caps;
+       return 0;
+}
+
+/*
+ * Fetch timestamps
+ */
+
+static inline int
+time_pps_fetch(
+       pps_handle_t            handle,
+       const int               tsformat,
+       pps_info_t *            pinfo,
+       const struct timespec * ptimeout
+       )
+{
+       pps_unit_t *    punit;
+       int             err;
+
+       /*
+        * Check for valid arguments and fetch timestamps
+        */
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       if (NULL == pinfo)
+               RETURN_PPS_ERRNO(EFAULT);
+
+       punit = unit_from_ppsapi_handle(handle);
+
+       if (NULL == punit)
+               RETURN_PPS_ERRNO(EBADF);
+
+       err = (*punit->provider->ptime_pps_fetch)(punit,
+                                                 punit->context, 
+                                                 tsformat, 
+                                                 pinfo, 
+                                                 ptimeout);
+
+       if (err)
+               RETURN_PPS_ERRNO(err);
+       else
+               return 0;
+}
+
+/*
+ * time_pps_kcbind - specify kernel consumer
+ *
+ * Not supported so far by Windows.
+ */
+
+static inline int
+time_pps_kcbind(
+       pps_handle_t handle,
+       const int kernel_consumer,
+       const int edge, const int tsformat
+       )
+{
+       pps_unit_t *    punit;
+       int             err;
+
+       if (!handle)
+               RETURN_PPS_ERRNO(EBADF);
+
+       punit = unit_from_ppsapi_handle(handle);
+
+       if (NULL == punit)
+               RETURN_PPS_ERRNO(EBADF);
+
+       err = (*punit->provider->ptime_pps_kcbind)(
+               punit,
+               punit->context,
+               kernel_consumer,
+               edge,
+               tsformat);
+
+       if (err)
+               RETURN_PPS_ERRNO(err);
+       else
+               return 0;
+}
+
+
+#endif /* TIMEPPS_H */
index 26eb8a25e7e3740ce57c9d5524096b9aedc9472f..e3324a66ec6b02aac65b8b47e47ccfce641d2949 100644 (file)
@@ -4,6 +4,7 @@
        Version="9.00"
        Name="instsrv"
        ProjectGUID="{C3534C4D-6DF1-498E-9904-4337878A1515}"
+       RootNamespace="instsrv"
        TargetFrameworkVersion="0"
        >
        <Platforms>
@@ -16,8 +17,8 @@
        <Configurations>
                <Configuration
                        Name="Debug|Win32"
-                       OutputDirectory=".\Debug"
-                       IntermediateDirectory=".\Debug"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
@@ -38,7 +39,7 @@
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Debug\Instsrv.tlb"
+                               TypeLibraryName="$(IntDir)Instsrv.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                WholeProgramOptimization="true"
                                AdditionalIncludeDirectories="..\..\..\..\include,..\..\include,..\..\instsrv"
                                PreprocessorDefinitions="_DEBUG;_CONSOLE;WIN32;SYS_WINNT;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS"
+                               StringPooling="true"
                                MinimalRebuild="false"
+                               ExceptionHandling="0"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
-                               PrecompiledHeaderFile=".\Debug\Instsrv.pch"
-                               AssemblerListingLocation=".\Debug\"
-                               ObjectFile=".\Debug\"
-                               ProgramDataBaseFileName="..\bin\Debug\instsrv-vc90"
+                               PrecompiledHeaderFile="$(IntDir)Instsrv.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)instsrv-vc90"
                                BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="oldnames.lib"
-                               OutputFile="..\bin\Debug\Instsrv.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Debug\Instsrv.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                LinkTimeCodeGeneration="1"
                                RandomizedBaseAddress="1"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Debug\Instsrv.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
                </Configuration>
                <Configuration
                        Name="Release|Win32"
-                       OutputDirectory=".\Release"
-                       IntermediateDirectory=".\Release"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Release\Instsrv.tlb"
+                               TypeLibraryName="$(IntDir)Instsrv.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                AdditionalIncludeDirectories="..\..\..\..\include,..\..\include,..\..\instsrv"
                                PreprocessorDefinitions="NDEBUG;_CONSOLE;WIN32;_WINDOWS;SYS_WINNT;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS"
                                StringPooling="true"
+                               ExceptionHandling="0"
                                RuntimeLibrary="0"
                                EnableFunctionLevelLinking="true"
-                               PrecompiledHeaderFile=".\Release\Instsrv.pch"
-                               AssemblerListingLocation=".\Release\"
-                               ObjectFile=".\Release\"
-                               ProgramDataBaseFileName="..\bin\Release\instsrv-vc90"
+                               PrecompiledHeaderFile="$(IntDir)Instsrv.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)instsrv-vc90"
+                               BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                                DebugInformationFormat="3"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="oldnames.lib"
-                               OutputFile="..\bin\Release\Instsrv.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Release\Instsrv.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                RandomizedBaseAddress="1"
                                DataExecutionPrevention="0"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Release\Instsrv.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
index 4c1a0dc7520db30f639c1ba7dd0c6ce1db73a9c6..f9f57507d4d26b425af3a7c29d092ec989652b73 100644 (file)
@@ -16,8 +16,8 @@
        <Configurations>
                <Configuration
                        Name="Debug|Win32"
-                       OutputDirectory=".\Debug"
-                       IntermediateDirectory=".\Debug"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="4"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
                                WholeProgramOptimization="false"
                                AdditionalIncludeDirectories="..\..\libntp,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC),..\..\..\..\sntp\libopts"
                                PreprocessorDefinitions="_DEBUG;_LIB;WIN32;SYS_WINNT;HAVE_CONFIG_H"
-                               MinimalRebuild="true"
+                               StringPooling="true"
+                               MinimalRebuild="false"
+                               ExceptionHandling="0"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
-                               PrecompiledHeaderFile=".\Debug\libntp.pch"
-                               AssemblerListingLocation=".\Debug\"
-                               ObjectFile=".\Debug\"
-                               ProgramDataBaseFileName=".\Debug\"
+                               PrecompiledHeaderFile="$(IntDir)libntp.pch"
+                               AssemblerListingLocation="$IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(IntDir)"
                                BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
@@ -72,7 +74,6 @@
                        />
                        <Tool
                                Name="VCLibrarianTool"
-                               OutputFile=".\Debug\libntp.lib"
                                SuppressStartupBanner="true"
                        />
                        <Tool
@@ -84,7 +85,7 @@
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Debug\libntp.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
@@ -95,8 +96,8 @@
                </Configuration>
                <Configuration
                        Name="Release|Win32"
-                       OutputDirectory=".\Release"
-                       IntermediateDirectory=".\Release"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="4"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
                                PreprocessorDefinitions="NDEBUG;_LIB;WIN32;SYS_WINNT;HAVE_CONFIG_H"
                                GeneratePreprocessedFile="0"
                                StringPooling="true"
+                               MinimalRebuild="false"
                                ExceptionHandling="0"
                                RuntimeLibrary="0"
                                EnableFunctionLevelLinking="false"
-                               PrecompiledHeaderFile=".\Release\libntp.pch"
-                               AssemblerListingLocation=".\Release\"
-                               ObjectFile=".\Release\"
-                               ProgramDataBaseFileName=".\Release\"
+                               PrecompiledHeaderFile="$(IntDir)libntp.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(IntDir)"
                                BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                        />
                        <Tool
                                Name="VCLibrarianTool"
-                               OutputFile=".\Release\libntp.lib"
                                SuppressStartupBanner="true"
                        />
                        <Tool
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Release\libntp.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
diff --git a/ports/winnt/vs2008/loopback-pps/loopback-ppsapi-provider.vcproj b/ports/winnt/vs2008/loopback-pps/loopback-ppsapi-provider.vcproj
new file mode 100644 (file)
index 0000000..e306108
--- /dev/null
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="loopback-ppsapi-provider"
+       ProjectGUID="{1ACE209D-D56E-450B-8711-B73E4ACFC38E}"
+       RootNamespace="loopbackerialppsapiprovider"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="196613"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
+                       ConfigurationType="2"
+                       CharacterSet="2"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="..\..\ntpd,..\..\..\..\ntpd,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include"
+                               PreprocessorDefinitions="SYS_WINNT"
+                               StringPooling="true"
+                               MinimalRebuild="false"
+                               ExceptionHandling="0"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="1"
+                               UsePrecompiledHeader="0"
+                               PrecompiledHeaderThrough="serialpps-ppsapi-provider.h"
+                               AssemblerListingLocation="$(IntDir)\"
+                               ProgramDataBaseFileName="$(OutDir)loopback-ppsapi-provider-vc90"
+                               BrowseInformation="1"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                               CompileAs="1"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="ntpd.lib"
+                               OutputFile="$(OutDir)$(ProjectName).dll"
+                               Version="0x0400"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="$(OutDir)"
+                               GenerateManifest="false"
+                               ModuleDefinitionFile="..\..\ppsapi\loopback\src\loopback-ppsapi.def"
+                               GenerateDebugInformation="true"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
+                               SubSystem="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
+                       ConfigurationType="2"
+                       CharacterSet="2"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               EnableIntrinsicFunctions="true"
+                               AdditionalIncludeDirectories="..\..\ntpd,..\..\..\..\ntpd,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include"
+                               PreprocessorDefinitions="SYS_WINNT"
+                               StringPooling="true"
+                               MinimalRebuild="false"
+                               ExceptionHandling="0"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               UsePrecompiledHeader="0"
+                               PrecompiledHeaderThrough="serialpps-ppsapi-provider.h"
+                               AssemblerListingLocation="$(IntDir)\"
+                               ProgramDataBaseFileName="$(OutDir)loopback-ppsapi-provider-vc90"
+                               BrowseInformation="1"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                               CompileAs="1"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="ntpd.lib"
+                               OutputFile="$(OutDir)$(ProjectName).dll"
+                               Version="0x0400"
+                               LinkIncremental="1"
+                               AdditionalLibraryDirectories="$(OutDir)"
+                               GenerateManifest="false"
+                               ModuleDefinitionFile="..\..\ppsapi\loopback\src\loopback-ppsapi.def"
+                               GenerateDebugInformation="true"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
+                               SubSystem="2"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+               <ProjectReference
+                       ReferencedProjectIdentifier="{400FBFCB-462E-40D0-B06B-3B74E3FFFD00}"
+                       CopyLocal="false"
+                       CopyLocalDependencies="false"
+                       CopyLocalSatelliteAssemblies="false"
+                       RelativePathToProject=".\libntp\libntp.vcproj"
+               />
+               <ProjectReference
+                       ReferencedProjectIdentifier="{CB61F8BF-9637-495C-9087-E8664B400CE0}"
+                       CopyLocal="false"
+                       CopyLocalDependencies="false"
+                       CopyLocalSatelliteAssemblies="false"
+                       RelativePathToProject=".\ntpd\ntpd.vcproj"
+               />
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath="..\..\ppsapi\loopback\src\loopback-ppsapi.c"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath="..\..\ppsapi\loopback\src\loopback-ppsapi.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\ppsapi\loopback\src\sys\time.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\ppsapi\loopback\src\timepps.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+               <File
+                       RelativePath=".\ReadMe.txt"
+                       >
+               </File>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
index 87831a2fe3ad16a5d01fd75fe7ce6e108f434832..6bf76fe93cf6b09746271af8832fa8fe9fec9025 100644 (file)
@@ -17,8 +17,8 @@
        <Configurations>
                <Configuration
                        Name="Debug|Win32"
-                       OutputDirectory=".\Debug"
-                       IntermediateDirectory=".\Debug"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
@@ -40,7 +40,7 @@
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Debug\ntp-keygen.tlb"
+                               TypeLibraryName="$(IntDir)ntp-keygen.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                WholeProgramOptimization="true"
                                AdditionalIncludeDirectories="..\..\ntp-keygen,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC),..\..\..\..\sntp\libopts"
                                PreprocessorDefinitions="_DEBUG;_CONSOLE;WIN32;__STDC__;SYS_WINNT;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS"
-                               MinimalRebuild="true"
+                               StringPooling="true"
+                               MinimalRebuild="false"
                                ExceptionHandling="0"
                                BasicRuntimeChecks="3"
                                SmallerTypeCheck="true"
                                RuntimeLibrary="1"
-                               PrecompiledHeaderFile=".\Debug\ntp-keygen.pch"
-                               AssemblerListingLocation=".\Debug\"
-                               ObjectFile=".\Debug\"
-                               ProgramDataBaseFileName="..\bin\Debug\ntp-keygen-vc90"
+                               PrecompiledHeaderFile="$(IntDir)ntp-keygen.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)ntp-keygen-vc90"
                                BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Debug\ntp-keygen.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Debug\ntp-keygen.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                LinkTimeCodeGeneration="1"
                                RandomizedBaseAddress="1"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Debug\ntp-keygen.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
                </Configuration>
                <Configuration
                        Name="Release|Win32"
-                       OutputDirectory=".\Release"
-                       IntermediateDirectory=".\Release"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Release\ntp-keygen.tlb"
+                               TypeLibraryName="$(IntDir)ntp-keygen.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                AdditionalIncludeDirectories="..\..\ntp-keygen,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC),..\..\..\..\sntp\libopts"
                                PreprocessorDefinitions="NDEBUG;_CONSOLE;WIN32;__STDC__;SYS_WINNT;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS"
                                StringPooling="true"
+                               MinimalRebuild="false"
+                               ExceptionHandling="0"
                                RuntimeLibrary="0"
                                EnableFunctionLevelLinking="true"
-                               PrecompiledHeaderFile=".\Release\ntp-keygen.pch"
-                               AssemblerListingLocation=".\Release\"
-                               ObjectFile=".\Release\"
-                               ProgramDataBaseFileName="..\bin\Release\ntp-keygen-vc90"
+                               PrecompiledHeaderFile="$(IntDir)ntp-keygen.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)ntp-keygen-vc90"
+                               BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                                DebugInformationFormat="3"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Release\ntp-keygen.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Release\ntp-keygen.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                LinkTimeCodeGeneration="0"
                                RandomizedBaseAddress="1"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Release\ntp-keygen.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
index 9821323d2c29ef47c855a32243e82950014b15e8..e5556d9043f4cb3521fd2f51a2061071b5e6d697 100644 (file)
@@ -36,6 +36,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntpd-keyword-gen", "ntpd-ke
                {400FBFCB-462E-40D0-B06B-3B74E3FFFD00} = {400FBFCB-462E-40D0-B06B-3B74E3FFFD00}
        EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loopback-ppsapi-provider", "loopback-pps\loopback-ppsapi-provider.vcproj", "{1ACE209D-D56E-450B-8711-B73E4ACFC38E}"
+       ProjectSection(ProjectDependencies) = postProject
+               {CB61F8BF-9637-495C-9087-E8664B400CE0} = {CB61F8BF-9637-495C-9087-E8664B400CE0}
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Win32 = Debug|Win32
@@ -74,6 +79,10 @@ Global
                {1B814CC1-EAD4-4A13-B29C-A67B23C9845A}.Debug|Win32.Build.0 = Debug|Win32
                {1B814CC1-EAD4-4A13-B29C-A67B23C9845A}.Release|Win32.ActiveCfg = Release|Win32
                {1B814CC1-EAD4-4A13-B29C-A67B23C9845A}.Release|Win32.Build.0 = Release|Win32
+               {1ACE209D-D56E-450B-8711-B73E4ACFC38E}.Debug|Win32.ActiveCfg = Debug|Win32
+               {1ACE209D-D56E-450B-8711-B73E4ACFC38E}.Debug|Win32.Build.0 = Debug|Win32
+               {1ACE209D-D56E-450B-8711-B73E4ACFC38E}.Release|Win32.ActiveCfg = Release|Win32
+               {1ACE209D-D56E-450B-8711-B73E4ACFC38E}.Release|Win32.Build.0 = Release|Win32
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
index 85696e0fc6645fdcbda691e3b75a5d4b0ef5de3b..9a309d24ec842e11eadd9e8f20421c3bd2dddaae 100644 (file)
@@ -17,8 +17,8 @@
        <Configurations>
                <Configuration
                        Name="Debug|Win32"
-                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-                       IntermediateDirectory="$(ConfigurationName)"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        CharacterSet="2"
                        >
                                AdditionalIncludeDirectories="..\..\ntpd,..\..\..\..\ntpd,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC),..\..\..\..\libopts"
                                PreprocessorDefinitions="_DEBUG;_CONSOLE;WIN32;SYS_WINNT;HAVE_CONFIG_H"
                                StringPooling="true"
-                               MinimalRebuild="true"
+                               MinimalRebuild="false"
                                ExceptionHandling="0"
                                BasicRuntimeChecks="3"
                                SmallerTypeCheck="true"
                                RuntimeLibrary="1"
                                EnableFunctionLevelLinking="true"
-                               ProgramDataBaseFileName="..\bin\Debug\keyword-gen-vc90"
+                               ProgramDataBaseFileName="$(OutDir)keyword-gen-vc90"
+                               BrowseInformation="1"
                                WarningLevel="4"
                                DebugInformationFormat="3"
                                CompileAs="1"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib winmm.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Debug\keyword-gen.exe"
+                               OutputFile="$(OutDir)keyword-gen.exe"
+                               Version="0x0400"
                                LinkIncremental="1"
                                GenerateDebugInformation="true"
+                               ProgramDatabaseFile="$(OutDir)keywordgen.pdb"
                                RandomizedBaseAddress="1"
                                TargetMachine="1"
                        />
@@ -83,6 +86,7 @@
                        />
                        <Tool
                                Name="VCBscMakeTool"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
                </Configuration>
                <Configuration
                        Name="Release|Win32"
-                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-                       IntermediateDirectory="$(ConfigurationName)"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        CharacterSet="2"
                        WholeProgramOptimization="1"
                                AdditionalIncludeDirectories="..\..\ntpd,..\..\..\..\ntpd,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC),..\..\..\..\libopts"
                                PreprocessorDefinitions="_CONSOLE;WIN32;SYS_WINNT;HAVE_CONFIG_H"
                                StringPooling="true"
+                               MinimalRebuild="false"
+                               ExceptionHandling="0"
                                RuntimeLibrary="0"
                                EnableFunctionLevelLinking="true"
-                               ProgramDataBaseFileName="..\bin\Release\keyword-gen-vc90"
+                               ProgramDataBaseFileName="$(OutDir)keyword-gen-vc90"
+                               BrowseInformation="1"
                                WarningLevel="4"
                                DebugInformationFormat="3"
                        />
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib winmm.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Release\keyword-gen.exe"
+                               OutputFile="$(OutDir)keyword-gen.exe"
+                               Version="0x0400"
                                LinkIncremental="1"
                                GenerateDebugInformation="true"
+                               ProgramDatabaseFile="$(OutDir)keywordgen.pdb"
                                OptimizeReferences="2"
                                EnableCOMDATFolding="2"
                                TargetMachine="1"
                        />
                        <Tool
                                Name="VCBscMakeTool"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
index dd27d216cecf782ceceb70fb8d95b584b4b9e432..b5c676078b839865ff17f31d3afb4498466a3247 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
        ProjectType="Visual C++"
-       Version="9.00"
+       Version="9,00"
        Name="ntpd"
        ProjectGUID="{CB61F8BF-9637-495C-9087-E8664B400CE0}"
        TargetFrameworkVersion="0"
@@ -16,8 +16,8 @@
        <Configurations>
                <Configuration
                        Name="Release|Win32"
-                       OutputDirectory=".\Release"
-                       IntermediateDirectory=".\Release"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
@@ -40,7 +40,7 @@
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Release\ntpd.tlb"
+                               TypeLibraryName="$(IntDir)ntpd.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                AdditionalIncludeDirectories="..\..\ntpd,..\..\..\..\ntpd,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC),..\..\..\..\sntp\libopts"
                                PreprocessorDefinitions="NDEBUG;_CONSOLE;WIN32;SYS_WINNT;HAVE_CONFIG_H"
                                StringPooling="true"
+                               MinimalRebuild="false"
                                ExceptionHandling="0"
                                RuntimeLibrary="0"
                                EnableFunctionLevelLinking="false"
-                               PrecompiledHeaderFile=".\Release\ntpd.pch"
-                               AssemblerListingLocation=".\Release\"
-                               ObjectFile=".\Release\"
-                               ProgramDataBaseFileName="..\bin\Release\ntpd-vc90"
+                               PrecompiledHeaderFile="$(IntDir)ntpd.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)ntpd-vc90"
                                BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib winmm.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Release\ntpd.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Release\ntpd.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                OptimizeForWindows98="0"
                                LinkTimeCodeGeneration="1"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Release\ntpd.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
                </Configuration>
                <Configuration
                        Name="Debug|Win32"
-                       OutputDirectory=".\Debug"
-                       IntermediateDirectory=".\Debug"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Debug\ntpd.tlb"
+                               TypeLibraryName="$(IntDir)ntpd.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                AdditionalIncludeDirectories="..\..\ntpd,..\..\..\..\ntpd,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC),..\..\..\..\sntp\libopts"
                                PreprocessorDefinitions="_DEBUG;_CONSOLE;WIN32;SYS_WINNT;HAVE_CONFIG_H"
                                StringPooling="true"
-                               MinimalRebuild="true"
+                               MinimalRebuild="false"
                                ExceptionHandling="0"
                                BasicRuntimeChecks="3"
                                SmallerTypeCheck="true"
                                RuntimeLibrary="1"
                                EnableFunctionLevelLinking="true"
-                               PrecompiledHeaderFile=".\Debug\ntpd.pch"
-                               AssemblerListingLocation=".\Debug\"
-                               ObjectFile=".\Debug\"
-                               ProgramDataBaseFileName="..\bin\Debug\ntpd-vc90"
+                               PrecompiledHeaderFile="$(IntDir)ntpd.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)ntpd-vc90"
                                BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib winmm.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Debug\ntpd.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Debug\ntpd.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                OptimizeForWindows98="0"
                                LinkTimeCodeGeneration="0"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Debug\ntpd.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
                                        <Tool
                                                Name="VCCustomBuildTool"
                                                Description="invoking keyword-gen on ntp_parser.h to produce ntp_keyword.h"
-                                               CommandLine=".\gen-ntp_keyword ..\bin\Release&#x0D;&#x0A;"
+                                               CommandLine=".\gen-ntp_keyword $(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)&#x0D;&#x0A;"
                                                AdditionalDependencies="..\..\..\..\ntpd\ntp_parser.h"
                                                Outputs="..\..\..\..\ntpd\ntp_keyword.h ..\..\..\..\ntpd\keyword-gen-utd"
                                        />
                                        <Tool
                                                Name="VCCustomBuildTool"
                                                Description="invoking keyword-gen on ntp_parser.h to produce ntp_keyword.h"
-                                               CommandLine=".\gen-ntp_keyword ..\bin\Debug&#x0D;&#x0A;"
+                                               CommandLine=".\gen-ntp_keyword $(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)&#x0D;&#x0A;"
                                                AdditionalDependencies="..\..\..\..\ntpd\ntp_parser.h"
                                                Outputs="..\..\..\..\ntpd\ntp_keyword.h ..\..\..\..\ntpd\keyword-gen-utd"
                                        />
index 5025c67a93cbae4b52ef77f4445754bd8320b0af..85a4bef373ca8709e76c54be72f4bba3c66633e4 100644 (file)
@@ -16,8 +16,8 @@
        <Configurations>
                <Configuration
                        Name="Debug|Win32"
-                       OutputDirectory=".\Debug"
-                       IntermediateDirectory=".\Debug"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
@@ -39,7 +39,7 @@
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Debug\ntpdate.tlb"
+                               TypeLibraryName="$(IntDir)ntpdate.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                WholeProgramOptimization="false"
                                AdditionalIncludeDirectories="..\..\ntpdate,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC)"
                                PreprocessorDefinitions="_DEBUG;_CONSOLE;WIN32;__STDC__;SYS_WINNT;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS"
-                               MinimalRebuild="true"
+                               StringPooling="true"
+                               MinimalRebuild="false"
+                               ExceptionHandling="0"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
-                               PrecompiledHeaderFile=".\Debug\ntpdate.pch"
-                               AssemblerListingLocation=".\Debug\"
-                               ObjectFile=".\Debug\"
-                               ProgramDataBaseFileName="..\bin\Debug\ntpdate-vc90"
+                               PrecompiledHeaderFile="$(IntDir)ntpdate.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)ntpdate-vc90"
                                BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Debug\ntpdate.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Debug\ntpdate.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                LinkTimeCodeGeneration="0"
                                RandomizedBaseAddress="1"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Debug\ntpdate.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
                </Configuration>
                <Configuration
                        Name="Release|Win32"
-                       OutputDirectory=".\Release"
-                       IntermediateDirectory=".\Release"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Release\ntpdate.tlb"
+                               TypeLibraryName="$(IntDir)ntpdate.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                AdditionalIncludeDirectories="..\..\ntpdate,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC)"
                                PreprocessorDefinitions="NDEBUG;_CONSOLE;WIN32;__STDC__;SYS_WINNT;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS"
                                StringPooling="true"
+                               MinimalRebuild="false"
+                               ExceptionHandling="0"
                                RuntimeLibrary="0"
                                EnableFunctionLevelLinking="true"
-                               PrecompiledHeaderFile=".\Release\ntpdate.pch"
-                               AssemblerListingLocation=".\Release\"
-                               ObjectFile=".\Release\"
-                               ProgramDataBaseFileName="..\bin\Release\ntpdate-vc90"
+                               PrecompiledHeaderFile="$(IntDir)ntpdate.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)ntpdate-vc90"
+                               BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                                DebugInformationFormat="3"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Release\ntpdate.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Release\ntpdate.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                LinkTimeCodeGeneration="1"
                                RandomizedBaseAddress="1"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Release\ntpdate.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
index c846247413e6aed26d3cd944cb0e0d9c167e2aa5..5fd301ddf8b542206e06e5309a43c7f2ca9f132c 100644 (file)
@@ -16,8 +16,8 @@
        <Configurations>
                <Configuration
                        Name="Debug|Win32"
-                       OutputDirectory=".\Debug"
-                       IntermediateDirectory=".\Debug"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
@@ -39,7 +39,7 @@
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Debug\ntpdc.tlb"
+                               TypeLibraryName="$(IntDir)ntpdc.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                WholeProgramOptimization="true"
                                AdditionalIncludeDirectories="..\..\ntpdc,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC),..\..\..\..\sntp\libopts"
                                PreprocessorDefinitions="_DEBUG;_CONSOLE;WIN32;__STDC__;SYS_WINNT;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS"
-                               MinimalRebuild="true"
+                               StringPooling="true"
+                               MinimalRebuild="false"
+                               ExceptionHandling="0"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
-                               PrecompiledHeaderFile=".\Debug\ntpdc.pch"
-                               AssemblerListingLocation=".\Debug\"
-                               ObjectFile=".\Debug\"
-                               ProgramDataBaseFileName="..\bin\Debug\ntpdc-vc90"
+                               PrecompiledHeaderFile="$(IntDir)ntpdc.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)ntpdc-vc90"
                                BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Debug\ntpdc.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Debug\ntpdc.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                LinkTimeCodeGeneration="1"
                                RandomizedBaseAddress="1"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Debug\ntpdc.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
                </Configuration>
                <Configuration
                        Name="Release|Win32"
-                       OutputDirectory=".\Release"
-                       IntermediateDirectory=".\Release"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Release\ntpdc.tlb"
+                               TypeLibraryName="$(IntDir)ntpdc.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                AdditionalIncludeDirectories="..\..\ntpdc,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC),..\..\..\..\sntp\libopts"
                                PreprocessorDefinitions="NDEBUG;_CONSOLE;WIN32;__STDC__;SYS_WINNT;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS"
                                StringPooling="true"
+                               MinimalRebuild="false"
+                               ExceptionHandling="0"
                                RuntimeLibrary="0"
                                EnableFunctionLevelLinking="true"
-                               PrecompiledHeaderFile=".\Release\ntpdc.pch"
-                               AssemblerListingLocation=".\Release\"
-                               ObjectFile=".\Release\"
-                               ProgramDataBaseFileName="..\bin\Release\ntpdc-vc90"
+                               PrecompiledHeaderFile="$(IntDir)ntpdc.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)ntpdc-vc90"
+                               BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                                DebugInformationFormat="3"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Release\ntpdc.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Release\ntpdc.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                LinkTimeCodeGeneration="0"
                                RandomizedBaseAddress="1"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Release\ntpdc.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
index f5a91c78cc54a04c88e2d694587cce9cbf110f96..440b38bae97ac1d1b3d739838196e3f3655bd1fc 100644 (file)
@@ -16,8 +16,8 @@
        <Configurations>
                <Configuration
                        Name="Release|Win32"
-                       OutputDirectory=".\Release"
-                       IntermediateDirectory=".\Release"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
@@ -39,7 +39,7 @@
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Release\ntpq.tlb"
+                               TypeLibraryName="$(IntDir)ntpq.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                AdditionalIncludeDirectories="..\..\ntpq,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC),..\..\..\..\sntp\libopts"
                                PreprocessorDefinitions="NDEBUG;_CONSOLE;WIN32;SYS_WINNT;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS"
                                StringPooling="true"
+                               MinimalRebuild="false"
+                               ExceptionHandling="0"
                                RuntimeLibrary="0"
                                EnableFunctionLevelLinking="true"
-                               PrecompiledHeaderFile=".\Release\ntpq.pch"
-                               AssemblerListingLocation=".\Release\"
-                               ObjectFile=".\Release\"
-                               ProgramDataBaseFileName="..\bin\Release\ntpq-vc90"
+                               PrecompiledHeaderFile="$(IntDir)ntpq.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)ntpq-vc90"
+                               BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                                DebugInformationFormat="3"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Release\ntpq.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Release\ntpq.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                LinkTimeCodeGeneration="0"
                                RandomizedBaseAddress="1"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Release\ntpq.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"
                </Configuration>
                <Configuration
                        Name="Debug|Win32"
-                       OutputDirectory=".\Debug"
-                       IntermediateDirectory=".\Debug"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)-bin\$(ConfigurationName)\"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)-tmp\$(ConfigurationName)\$(TargetName)\"
                        ConfigurationType="1"
                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
                        UseOfMFC="0"
                        />
                        <Tool
                                Name="VCMIDLTool"
-                               TypeLibraryName=".\Debug\ntpq.tlb"
+                               TypeLibraryName="$(IntDir)ntpq.tlb"
                                HeaderFileName=""
                        />
                        <Tool
                                WholeProgramOptimization="true"
                                AdditionalIncludeDirectories="..\..\ntpq,..\..\include,..\..\..\..\include,..\..\..\..\lib\isc\win32\include,..\..\..\..\lib\isc\include,$(OPENSSL_INC),..\..\..\..\sntp\libopts"
                                PreprocessorDefinitions="_DEBUG;_CONSOLE;WIN32;;SYS_WINNT;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS"
-                               MinimalRebuild="true"
+                               StringPooling="true"
+                               MinimalRebuild="false"
+                               ExceptionHandling="0"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
-                               PrecompiledHeaderFile=".\Debug\ntpq.pch"
-                               AssemblerListingLocation=".\Debug\"
-                               ObjectFile=".\Debug\"
-                               ProgramDataBaseFileName="..\bin\Debug\ntpq-vc90"
+                               PrecompiledHeaderFile="$(IntDir)ntpq.pch"
+                               AssemblerListingLocation="$(IntDir)"
+                               ObjectFile="$(IntDir)"
+                               ProgramDataBaseFileName="$(OutDir)ntpq-vc90"
                                BrowseInformation="1"
                                WarningLevel="4"
                                SuppressStartupBanner="true"
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalDependencies="ws2_32.lib $(OPENSSL_LIB)\libeay32.lib"
-                               OutputFile="..\bin\Debug\ntpq.exe"
+                               OutputFile="$(OutDir)$(ProjectName).exe"
                                Version="0x0400"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
                                GenerateDebugInformation="true"
-                               ProgramDatabaseFile="..\bin\Debug\ntpq.pdb"
+                               ProgramDatabaseFile="$(OutDir)$(ProjectName).pdb"
                                SubSystem="1"
                                LinkTimeCodeGeneration="1"
                                RandomizedBaseAddress="1"
                        <Tool
                                Name="VCBscMakeTool"
                                SuppressStartupBanner="true"
-                               OutputFile=".\Debug\ntpq.bsc"
+                               OutputFile="$(IntDir)/$(ProjectName).bsc"
                        />
                        <Tool
                                Name="VCFxCopTool"