//Winflux is written by Joe Verfaillie with the Global Change Research //Group at San Diego State University and based on the DOS eddy flux //program written by Tilden Myers at NOAA/ATDD. This is freeware and //may not be sold in any form. // Version Nov 2004. Checked for use by UC Berkeley Biomet Lab and applied to WindMaster Pro // Compiled in Microsoft C++ D. Baldocchi // Program writes raw data at 2 byte words for first 4 channels (w,u,v & T) and as // 4 byte words for additional analog channels // changed name of setup file to setup.win #include #include #include #include #include "fluxr3.h" int WINAPI WinMain( HINSTANCE hInst, /*Win32 entry-point routine */ HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow ) { MSG lpMsg; WNDCLASS wc; RECT theRect; if( !hPreInst ) /*set up window class and register it */ { wc.lpszClassName = szProgName; wc.hInstance = hInst; wc.lpfnWndProc = WndProc; wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.lpszMenuName = NULL; wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); wc.style = 0; wc.cbClsExtra = 0; wc.cbWndExtra = 0; if( !RegisterClass( &wc ) ) return FALSE; } ghwndMain = CreateWindow( szProgName, /* now create the window */ "WinFluxWMP v1.0", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND)NULL, (HMENU)NULL, (HINSTANCE)hInst, (LPSTR)NULL ); GetClientRect(ghwndMain, &theRect); wheight = theRect.bottom - 60; rect1.bottom = theRect.bottom; mainThreadId = GetCurrentThreadId(); ReadSetupFile(); op_file(); InitTTYInfo(); InitGraphics(); ShowWindow(ghwndMain, nCmdShow ); UpdateWindow( ghwndMain ); SetupCommPort(); while( GetMessage( &lpMsg, NULL, 0, 0 ) ) // begin the message loop { TranslateMessage( &lpMsg ); if(lpMsg.message == WM_USER+1 || lpMsg.message == WM_USER+2) lpMsg.hwnd = ghwndMain; DispatchMessage( &lpMsg ); } return( lpMsg.wParam); } LRESULT CALLBACK WndProc( HWND hWnd, UINT messg, //callback procedure WPARAM wParam, LPARAM lParam ) { HDC hdc; // handle to the device context char msg[6]; BYTE *c; DWORD count; short i; switch(messg) { case WM_PAINT: PaintWindow(hWnd); break; case WM_USER+1: //main loop hdc = GetDC(ghwndMain); //write raw data to file c = (BYTE*)lParam; wsprintf(msg, "%05d", wParam); if(raw_op > 0) WriteFile(fptr1, c+2, amountToRead-4, &count, NULL); //comment out the line above and un-comment the line below to write error //and status bytes // WriteFile(fptr1, c, wParam, &count, NULL); TextOut(hdc, 150, 0, msg, 5); ReleaseDC(ghwndMain, hdc); ProcessMessage(c); cal_stat(); GraphData(); for(i=3; i= 200) lag[i] = 0; } index++; //increment index if(index == 200) index=0; break; case WM_USER+2: //20 second init loop hdc = GetDC(ghwndMain); wsprintf(msg, "%05d", index); TextOut(hdc, 150, 0, msg, 5); ReleaseDC(ghwndMain, hdc); //write init data to raw file c = (BYTE*)lParam; if(raw_op > 0) WriteFile(fptr1, c+2, amountToRead-4, &count, NULL); //comment out the line above and un-comment the line below to write error //and status bytes // WriteFile(fptr1, c, wParam, &count, NULL); ProcessMessage(c); InitStats(); break; case WM_USER+3: //serial port timed out hdc = GetDC(ghwndMain); TextOut(hdc, 150, 0, "-CCK-", 5); ReleaseDC(ghwndMain, hdc); c = (BYTE*)lParam; ChannelCheck(c, wParam); break; case WM_SIZE: //window resized rect1.bottom = HIWORD(lParam); wheight = HIWORD(lParam) - 60; InvalidateRect(ghwndMain, NULL, TRUE); return( DefWindowProc( hWnd, messg, wParam, lParam ) ); break; case WM_DESTROY: BreakDownCommPort(); if(fptr1 != INVALID_HANDLE_VALUE) CloseHandle(fptr1); // if(fptr2 != INVALID_HANDLE_VALUE) // CloseHandle(fptr2); PostQuitMessage(0); break; default: return( DefWindowProc( hWnd, messg, wParam, lParam ) ); } return( 0L ); } BOOL ReadSetupFile(void) { int i,time_const; double constant; FILE *setup=NULL; short d,r; setup = fopen("setup.win","r"); if(setup == NULL) { ReportError("ReadSetup"); return FALSE; } fscanf(setup,"%*s %d %*s %d %*s %d", &boom, &raw_op, &nch); fscanf(setup,"%*s %s", diskr); fscanf(setup,"%*s %s", diskd); fscanf(setup,"%*s %d", &port_num); fscanf(setup,"%*s %*d"); //, &print_op); fscanf(setup,"%*s %d", &sample_rate); fscanf(setup,"%*s %d", &time_const); fscanf(setup,"%*s %*s %*s"); //get disk volume labels from path name for(i=0; itm_year - 100; if((year - 1988)%4 == 0) mon[1] = 29; // check for leap year jday = now->tm_mday; for (i = 0; i < (now->tm_mon); i++) //calculate julian day jday += mon[i]; //build file names wsprintf(rfname,"%s%02d%03d%02d%02d%s",diskr,year,jday,now->tm_hour,now->tm_min,".raw"); if(fcheck == 0) { wsprintf(fname,"%s%02d%s%03d%s",diskd,year,"_",jday,".flx"); wsprintf(ufname,"%s%02d%s%03d%s",diskd,year,"_",jday,".nrt"); wsprintf(efname,"%s%02d%s%03d%s",diskd,year,"_",jday,".err"); fcheck = 1; } //open raw file if necessary if(raw_op > 0) { if(fptr1 != INVALID_HANDLE_VALUE) CloseHandle(fptr1); fptr1 = CreateFile(rfname, // create raw file GENERIC_WRITE, // open for writing 0, // do not share NULL, // no security CREATE_ALWAYS, // overwrite existing FILE_ATTRIBUTE_NORMAL, // normal file NULL); // no attr. template if (fptr1 == INVALID_HANDLE_VALUE) ReportError("Could not open file."); // process error } } HANDLE SetupCommPort(void) { char comport[3][5]={" ", "COM1", "COM2"}; //char comport[6][5]={" ", "COM1", "COM2","COM3", "COM4","COM5"}; // // open communication port handle // TTYInfo.hCommPort = CreateFile( comport[port_num], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (TTYInfo.hCommPort == INVALID_HANDLE_VALUE) { ReportError("CreateFile"); return NULL; } // // Save original comm timeouts and set new ones // if (!GetCommTimeouts( TTYInfo.hCommPort, &(TTYInfo.timeoutsorig))) ReportError("GetCommTimeouts"); // // Set port state // UpdateConnection(); // // set comm buffer sizes // SetupComm(TTYInfo.hCommPort, MAX_READ_BUFFER, MAX_WRITE_BUFFER); // // start threads and set initial thread state to not done // StartThreads(); // // set overall connect flag // TTYInfo.fConnected = TRUE ; return TTYInfo.hCommPort; } BOOL UpdateConnection(void) { DCB dcb = {0}; dcb.DCBlength = sizeof(dcb); // // get current DCB settings // if (!GetCommState(TTYInfo.hCommPort, &dcb)) { ReportError("GetCommState"); return FALSE; } // // update DCB rate, byte size, parity, and stop bits size // dcb.BaudRate = 9600; //BAUDRATE(TTYInfo); dcb.ByteSize = 8; //BYTESIZE(TTYInfo); dcb.Parity = NOPARITY; //PARITY(TTYInfo); dcb.StopBits = ONESTOPBIT; //STOPBITS(TTYInfo); /* Additional serial port settings not needed by winflux // // update event flags // if (EVENTFLAGS(TTYInfo) & EV_RXFLAG) dcb.EvtChar = FLAGCHAR(TTYInfo); else dcb.EvtChar = '\0'; // // update flow control settings // dcb.fDtrControl = DTRCONTROL(TTYInfo); dcb.fRtsControl = RTSCONTROL(TTYInfo); dcb.fOutxCtsFlow = CTSOUTFLOW(TTYInfo); dcb.fOutxDsrFlow = DSROUTFLOW(TTYInfo); dcb.fDsrSensitivity = DSRINFLOW(TTYInfo); dcb.fOutX = XONXOFFOUTFLOW(TTYInfo); dcb.fInX = XONXOFFINFLOW(TTYInfo); dcb.fTXContinueOnXoff = TXAFTERXOFFSENT(TTYInfo); dcb.XonChar = XONCHAR(TTYInfo); dcb.XoffChar = XOFFCHAR(TTYInfo); dcb.XonLim = XONLIMIT(TTYInfo); dcb.XoffLim = XOFFLIMIT(TTYInfo); // // DCB settings not in the user's control // dcb.fParity = TRUE; */ // // set new state // if (!SetCommState(TTYInfo.hCommPort, &dcb)) { ReportError("SetCommState"); return FALSE; } // // set new timeouts // if (!SetCommTimeouts(TTYInfo.hCommPort, &gTimeoutsDefault)) { ReportError("SetCommTimeouts"); return FALSE; } return TRUE; } void StartThreads(void) { DWORD dwReadId; // // thread exit event // ghThreadExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (ghThreadExitEvent == NULL) ReportError("CreateEvent (Thread exit event)"); TTYInfo.hReader = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) ReaderProc, (LPVOID) &mainThreadId, 0, &dwReadId); if (TTYInfo.hReader == NULL) ReportError("CreateThread(Reader)"); return; } DWORD WINAPI ReaderProc(LPVOID threadId) { DWORD *tid; HDC hdc; tid = (DWORD*)threadId; OVERLAPPED osReader = {0}; // overlapped structure for read operations HANDLE hArray[NUM_READSTAT_HANDLES]; // DWORD dwStoredFlags = 0xFFFFFFFF; // local copy of event flags // DWORD dwCommEvent; // result from WaitCommEvent // DWORD dwOvRes; // result from GetOverlappedResult DWORD dwRead; // bytes actually read DWORD dwRes; // result from WaitForSingleObject BOOL fWaitingOnRead = FALSE; BOOL fThreadDone = FALSE; char *lpBuf; //[AMOUNT_TO_READ]; // // create overlapped structure for read events // osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (osReader.hEvent == NULL) ReportError("CreateEvent (Reader Event)"); // // We want to detect the following events: // Read events (from ReadFile) // Thread exit evetns (from our shutdown functions) // hArray[0] = osReader.hEvent; hArray[1] = ghThreadExitEvent; while(!fThreadDone) { // // if no read is outstanding, then issue another one // if(!fWaitingOnRead) { lpBuf = (char*)LocalAlloc(LPTR, amountToRead); if(lpBuf == NULL) { ReportError("Out of memory"); return 0; } if(!ReadFile(TTYInfo.hCommPort, lpBuf, amountToRead, &dwRead, &osReader)) { if(GetLastError() != ERROR_IO_PENDING) // read not delayed? ReportError("ReadFile in ReaderAndStatusProc"); else fWaitingOnRead = TRUE; } else // read completed immediately { // if ((dwRead != MAX_READ_BUFFER) && TTYInfo.fDisplayTimeouts) // UpdateStatus("Read timed out immediately.\r\n"); if(dwRead) PostThreadMessage(*tid, tMessage, dwRead, (long)lpBuf); } } // // wait for pending operations to complete // if(fWaitingOnRead) { dwRes = WaitForMultipleObjects(NUM_READSTAT_HANDLES, hArray, FALSE, READ_TIMEOUT); switch(dwRes) { // // read completed // case WAIT_OBJECT_0: if (!GetOverlappedResult(TTYInfo.hCommPort, &osReader, &dwRead, FALSE)) { if (GetLastError() == ERROR_OPERATION_ABORTED) ReportError("Read aborted\r\n"); else ReportError("GetOverlappedResult (in Reader)"); } else // read completed successfully { if ((dwRead != MAX_READ_BUFFER) && TTYInfo.fDisplayTimeouts) ReportError("Read timed out overlapped.\r\n"); if (dwRead) PostThreadMessage(*tid, tMessage, dwRead, (long)lpBuf); } fWaitingOnRead = FALSE; break; // // thread exit event // case WAIT_OBJECT_0 + 1: fThreadDone = TRUE; break; case WAIT_TIMEOUT: //report timeout to the screen hdc = GetDC(ghwndMain); TextOut(hdc, 150, 0, "-RTO-", 5); ReleaseDC(ghwndMain, hdc); break; default: ReportError("WaitForMultipleObjects(Reader & Status handles)"); break; } } } // // close event handles // CloseHandle(osReader.hEvent); return 1; } void ProcessMessage(unsigned char *c) { short i; // char msg[80]; // DWORD count; unsigned char n; short *ia; unsigned short *sos; long *an; static short m=10+(nch-4)*4; if(!(c[0] == 0x81 && c[1] == 0x81)) return; // Swap byte for first four, two-byte channels for(i=2; i<10; i+=2) { n = c[i]; c[i] = c[i+1]; c[i+1] = n; } // Swap bytes for any four-byte analog channels for(i=10; i 2) { wx[i] += (dat[0][lag[i]]-r_mean[0])*xp[i]; // w covariance ux[i] += (dat[1][lag[i]]-r_mean[1])*xp[i]; // u covariance vx[i] += (dat[2][lag[i]]-r_mean[2])*xp[i]; // v covariance } } ww += xp[0]*xp[0]; // velocity variances and covariances uu += xp[1]*xp[1]; vv += xp[2]*xp[2]; uw += xp[0]*xp[1]; uv += xp[1]*xp[2]; wv += xp[0]*xp[2]; time(&thyme); now = localtime(&thyme); min = now->tm_min+30; if(sample > 1200 && (min % 30 == 0)) { for (i=0; i .0001) { kurt[i] /= (fsample*vari[i]*vari[i]); skew[i] /= (fsample*vari[i]*sqrt(vari[i])); } else { kurt[i] = 999; skew[i] = 999; } } ww /= (float) sample; uu /= (float) sample; vv /= (float) sample; uw /= (float) sample; uv /= (float) sample; wv /= (float) sample; ws = sqrt(x_bar[1]*x_bar[1] + x_bar[2]*x_bar[2]); tw = sqrt(x_bar[0]*x_bar[0] + ws*ws); ce = x_bar[1]/ws; // cos eta se = x_bar[2]/ws; // sin eta ct = ws/tw; // cos theta st = x_bar[0]/tw; // sin theta theta = 180*acos(ct)/PI; // vertical eta = 180*acos(ce)/PI; // horizontal ce2 = ce*ce; se2 = se*se; ct2 = ct*ct; st2 = st*st; wdir =boom - (atan2(x_bar[2],x_bar[1]))*180.0/PI; if(wdir > 360.) wdir -= 360.0; if(wdir < 0.0) wdir += 360.0; u_bar = x_bar[1]*ct*ce + x_bar[2]*ct*se + x_bar[0]*st; v_bar = x_bar[2]*ce - x_bar[1]*se; w_bar = x_bar[0]*ct - x_bar[1]*st*ce - x_bar[2]*st*se; uur = uu*ct2*ce2 + 2*uv*ct2*ce*se + 2*uw*ct*ce*st + vv*ct2*se2 + 2*wv*ct*se*st + ww*st2; vvr = vv*ce2 + uu*se2 - 2*uv*ce*se; wwr = ww*ct2 + uu*st2*ce2 + vv*st2*se2 - 2*uw*ct*st*ce - 2*wv*ct*st*se + 2*uv*st2*ce*se; uwr = uw*ce*(ct2-st2) + wv*se*(ct2-st2) + ww*st*ct - uu*st*ct*ce2 - vv*st*ct*se2 - 2*uv*st*ct*se*ce; wvr = 0; if (uwr < 0) u_star = sqrt(-uwr); else u_star = -9999.; for (i = 3; i < nch; i++) wxr[i] = wx[i]*ct - ux[i]*st*ce - vx[i]*st*se; if(now->tm_hour==0 && now->tm_min == 30) fcheck = 0; op_file(); // generate filenames // // write 'flx' file // fptr3 = fopen(fname,"a"); if(fptr3 == NULL) ReportError("open flx file"); fprintf(fptr3,"%3d %02d%02d %4.0f ", jday,now->tm_hour, now->tm_min,wdir); fprintf(fptr3,"%4.2f %4.3e ",u_bar,uwr); for(i = 3; i < nch; i++) fprintf(fptr3,"%5.3f ", x_bar[i]); fprintf(fptr3,"%4.3e %4.3e %4.3e ",uur,vvr,wwr); for(i = 3; i < nch; i++) fprintf(fptr3," %4.3e",vari[i]); for (i = 3; i < nch; i++) fprintf(fptr3," %4.3e",wxr[i]); fprintf(fptr3," %u\n",sample); fclose(fptr3); // // write unrotated file // fptr3 = fopen(ufname,"a"); fprintf(fptr3,"%3d %02d%02d %4.0f ",jday,now->tm_hour, now->tm_min,wdir); fprintf(fptr3,"%5.3f %5.3f %5.3f ",x_bar[0], x_bar[1],x_bar[2]); fprintf(fptr3," %4.3e %4.3e %4.3e %4.3e %4.3e %4.3e ", ww,uu,vv,uw,uv,wv); for (i = 3; i < nch; i++) fprintf(fptr3," %4.3e %4.3e %4.3e %4.3e ",wx[i],ux[i], vx[i],vari[i]); fprintf(fptr3," %d\n",sample); fclose(fptr3); // // write 'err' file // fptr3 = fopen(efname,"a"); fprintf(fptr3,"%3d %02d%02d %4.0f ",jday,now->tm_hour, now->tm_min,wdir); for (i = 0; i < nch; i++) fprintf(fptr3," %4.3e ",skew[i]); for (i = 0; i < nch; i++) fprintf(fptr3," %4.3e ",kurt[i]); fprintf(fptr3," %4.0f %4.0f ", theta,eta); fprintf(fptr3," %d\n",sample); fclose(fptr3); /* if(raw_op > 0) { fclose(fptr1); fptr1 = fopen(rfname,"wb"); BOOL GetDiskFreeSpaceEx( LPCTSTR lpDirectoryName, // pointer to directory name on disk of interest PULARGE_INTEGER lpFreeBytesAvailableToCaller, // pointer to variable to receive free bytes on disk available to the caller PULARGE_INTEGER lpTotalNumberOfBytes, // pointer to variable to receive number of bytes on disk PULARGE_INTEGER lpTotalNumberOfFreeBytes); // pointer to variable to receive free bytes on disk disk_space(); sprintf(sptr,"%u",kbyte); putimage(140,30,buffer2,COPY_PUT); setcolor(15); outtextxy(140,30,sptr); } */ sample = 0; ClearStats(); } sample += 1; } void GraphData(void) { short i; static int scale[MAXCH] = {1,1,1,1,1,1,1,1,1,1}; static int y[MAXCH]; // data traces static int xold = 0; // initialize x position static int x = 1; // int p_buf; static float std[MAXCH]; double wdir,cdir,sdir; //theta,xdir,ydir; char sptr[200]; HDC hdc; // handle to the device context int n; struct tm *now; time_t thyme; time(&thyme); now = localtime(&thyme); hdc = GetDC(ghwndMain); if ((index+10) % 10 == 0) { wsprintf(sptr,"%02d:%02d:%02d",now->tm_hour,now->tm_min,now->tm_sec); // setcolor(15); // putimage(10,0,buffer2,COPY_PUT); // outtextxy(10,0,gtime); TextOut(hdc, 10,0,sptr, 8); /* if(raw_op) { putimage(500,18,buffer2,COPY_PUT); outtextxy(500,25,prnouty); } else { putimage(500,18,buffer2,COPY_PUT); } */ } if((xold+20) % 20 == 0) { if(x == 1) rect1.left = 0; //clear vertical strip else rect1.left = x; rect1.right = x+20; FillRect(hdc, &rect1, brush); /* for (i = 0; i < nch; i++) { std[i] = sqrt((var_scale[i]/420.)); var_scale[i] = 0.; if(std[i] > 0.005) { scale[i] = 25/(3*std[i]); if(scale[i] > 500) scale[i] = 500; } } */ for (i=0; i < nch; i++) //write channel values to screen { sprintf(sptr," %+5.3f %+5.3f%n",dat[i][index],std[i], &n); rect2.top = z[i]; rect2.bottom = z[i]+30; FillRect(hdc, &rect2, brush); TextOut(hdc, 465,z[i],sptr, n); } } for (i=0; i < nch; i++) //plot traces { // setcolor(col[i]); y[i] = z[i] - xp[i]*scale[i]; if(y[i] < 60) y[i] = 60; if(y[i] > (wheight+60)) y[i] = wheight; MoveToEx(hdc, xold, yold[i], NULL); LineTo(hdc, x, y[i]); yold[i] = y[i]; } if (dat[2][index] != 0 && index % 2 == 0) //draw wind rose { wdir =(boom*D2R) - (atan2(dat[2][index],dat[1][index])); if(wdir > TWOPI) wdir -= TWOPI; wdir = TWOPI - (wdir - PI/2); cdir = cos(wdir); sdir = sin(wdir); Ellipse(hdc, 475, 15, 515, 55); MoveToEx(hdc, 495+2*sdir, 35+2*cdir, NULL); LineTo(hdc, 495-13*cdir, 35+13*sdir); LineTo(hdc, 495-2*sdir, 35-2*cdir); wdir = wdir*180/PI - 90; if(wdir > 360) wdir -= 360; sprintf(sptr, "%03.0f", 360-wdir); TextOut(hdc, 519, 0, sptr, 3); } xold = x; x = x + 1; if(x == 420) { x = 1; xold=0; for (i = 0; i < nch; i++) //calculate new trace scales { std[i] = sqrt((var_scale[i]/wheight)); var_scale[i] = 0.; if(std[i] > 0.005) { scale[i] = 25/(3*std[i]); if(scale[i] > 500) scale[i] = 500; } } n = GetDiskSpace(sptr, vold); TextOut(hdc, 350, 20, sptr, n); if(raw_op) { n = GetDiskSpace(sptr, volr); TextOut(hdc, 350, 40, sptr, n); } } ReleaseDC(ghwndMain, hdc); return; } void PaintWindow(HWND hWnd) { HDC hdc; // handle to the device context PAINTSTRUCT pstruct; //struct for the call to BeginPaint // int horz, vert; time_t thyme; struct tm *now; short i; char str[40]; int n; GetClientRect(ghwndMain, &rc); hdc = BeginPaint(hWnd, &pstruct ); //prepare window for painting TextOut(hdc, 490, 0, "N", 1); //Wind Rose TextOut(hdc, 490, 57, "S", 1); TextOut(hdc, 519, 27, "E", 1); TextOut(hdc, 458, 27, "W", 1); Ellipse(hdc, 475, 15, 515, 55); for (i=0; i < nch; i++) { // setcolor(col[1]); z[i] = 60 + wheight*(2*i+1)/(2*nch); // z[i] = wheight*(i+1)/nch - wheight/(nch*2) + 60; yold[i] = z[i]; MoveToEx(hdc, 0, z[i], NULL); LineTo(hdc, 420,z[i]); TextOut(hdc, 430,z[i],var[i].name, var[i].nl); } time(&thyme); //current time now = localtime(&thyme); wsprintf(str, "%02d:%02d:%02d", now->tm_hour, now->tm_min, now->tm_sec); TextOut( hdc, 10, 0, str, 8); TextOut( hdc, 10, 20, fname, strlen(fname)); n = GetDiskSpace(str, vold); //file names and space TextOut(hdc, 350, 20, str, n); if(raw_op) { TextOut( hdc, 10, 40, rfname, strlen(rfname)); n = GetDiskSpace(str, volr); TextOut(hdc, 350, 40, str, n); } EndPaint(hWnd, &pstruct ); // stop painting } void InitStats(void) { short i; for (i=0; i 20) MessageBox(ghwndMain, "Message Length Failure", "Error", MB_OK); } int GetDiskSpace(char *str, char *vol) { ULARGE_INTEGER caller, total, free; // DWORD sectors, bytes, free, total, space; int n=0; char c[4][3]={"B", "kB", "MB", "GB"}; /* if(GetDiskFreeSpace(vol, §ors, &bytes, &free, &total)) { space = free*bytes/1024; sprintf(str, "%u %s Free%n", space, c[1], &n); } */ //uncomment section above for WIN95 and comment section below //* if(GetDiskFreeSpaceEx(vol, &caller, &total, &free)) { if(caller.HighPart > 0) { caller.HighPart *= 4; caller.LowPart = 0; n = 3; } else { while(caller.LowPart >= 1024) { caller.LowPart /= 1024; n++; } } caller.HighPart += caller.LowPart; sprintf(str, "%u %s Free%n", caller.HighPart, c[n], &n); } //* else { // ReportError("GetDiskFreeSpace failed"); sprintf(str, "GetDiskFreeSpace failed%n", &n); } return n; } BOOL BreakDownCommPort(void) { if (!TTYInfo.fConnected) return FALSE; TTYInfo.fConnected = FALSE; SetEvent(ghThreadExitEvent); // // wait for the threads for a small period // if(WaitForSingleObject(TTYInfo.hReader,2000)) ReportError("Error closing port."); ResetEvent(ghThreadExitEvent); // // restore original comm timeouts // if (!SetCommTimeouts(TTYInfo.hCommPort, &(TTYInfo.timeoutsorig))) ReportError("SetCommTimeouts (Restoration to original)"); /* // // Purge reads/writes, input buffer and output buffer // if (!PurgeComm(TTYInfo.hCommPort), PURGE_FLAGS)) ReportError("PurgeComm"); */ CloseHandle(TTYInfo.hCommPort); CloseHandle(TTYInfo.hReader); return TRUE; } void ReportError(char *szMessage) { DWORD errnum; char *msg=NULL, szBuffer[40]; DWORD dwRes = 0; errnum = GetLastError(); dwRes = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errnum, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPTSTR)szBuffer, 40, NULL); dwRes = strlen(szMessage) + dwRes + 20; msg = (char*)LocalAlloc(LPTR, dwRes); if(msg == NULL) MessageBox(ghwndMain, szMessage, NULL, MB_OK); else { wsprintf(msg, "%s\r\nError %d: %s", szMessage, errnum, szBuffer); MessageBox(ghwndMain, msg, NULL, MB_OK); } LocalFree(msg); }