Correction Step 2 is also causing issues. I had at one point thought it was an issue with my threading model, so I found a tutorial (with code samples) that showed a different ("Correct"er?) method of thread handling. I plugged my code into it in a piece by piece manner to see when/which part/if the error could be reproduced.
Unfortunately, the only thing this proved, was that my threading modle was fine... *sigh* But here are the relevent parts of the connection (Step 2) test that are causing the oprhand handle issue. Each time the code fires, the programs handle count (bizzarly)increases by one.
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int isSocWriteable(SOCKET s) { //======================================================================
struct timeval Timeout;
fd_set writefds;
int iResult;
writefds.fd_count = 1;
writefds.fd_array[0] = s; //====================== No Time to Loiter...
Timeout.tv_usec = 42000; //(dwMIN_Reply * 1000); //========== This is Measured in Microseconds!
Timeout.tv_sec = 0; // ^^^ Current Default is 62 Milliseconds (or 62000 Microseconds).
iResult = select(1, NULL, &writefds, NULL, &Timeout); //========== Get the Results...
return(iResult); //========================================== ...Return the Results.
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
///////////////////////////////////////////////
// PortScannerWindow::goScan
///////////////////////////////////////////////
BOOL PortScannerWindow::goScan() {
SOCKET lhSocket; // Our socket
SOCKADDR_IN lSockAddr; // The SOCKADDR_IN structure containing IP and port info
WSADATA wsaData; // WinSock config data structure
int lConnect; // Connection status flag
int StartPort;
int EndPort;
char* IPAddress;
BOOL bSuccess; // Success flag needed for GetDlgItemInt
char* buffer; // Buffer to hold updated info for the text output area
int nTxtLen;
// Get IP Address, Start Port and End Port
// Remember, we've already validated this input
IPAddress = GrabTextFromEdit(IDE_IPADDRESS);
StartPort = GetDlgItemInt(m_hWnd,IDE_STARTPORT,&bSuccess,FALSE);
EndPort = GetDlgItemInt(m_hWnd,IDE_ENDPORT, &bSuccess,FALSE);
// Initialize WinSock
if(WSAStartup(MAKEWORD(2,0),&wsaData) != 0)
{
MessageBox(m_hWnd, "Socket Initialization Error.", "Socket Error",
MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
// Allocate space for text output
buffer = (char*)malloc(100*sizeof(char));
// Loop through from StartPort to EndPort
for (int i=StartPort;i<=EndPort;i++) {
// Initialize Socket
lhSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(lhSocket == INVALID_SOCKET)
{
MessageBox(m_hWnd, "Invalid Socket.", "Socket Error",
MB_OK | MB_ICONEXCLAMATION);
}
linger ls = {1, 0}; //= ABSOLUTELY NO LOITERING - Get the Answer & Slam the ***
setsockopt(lhSocket, SOL_SOCKET, SO_LINGER, (LPSTR)&ls, sizeof(ls)); // Door Shut! ***
// Zero out SOCKADDR_IN structure
memset(&lSockAddr,0, sizeof(lSockAddr));
// Fill SOCKADDR_IN structure
lSockAddr.sin_family = AF_INET;
lSockAddr.sin_port = htons(i);
lSockAddr.sin_addr.s_addr = inet_addr(IPAddress);
/*------------------------------------------------------------->
Set Socket I/O mode: In this case FIONBIO Enables or Disables
the Sockets Blocking Mode Based on the Numeric Value of iMode.
If iMode != 0, non-blocking mode is enabled.
If iMode = 0, blocking is enabled;
<-------------------------------------------------------------*/
int iMode = 1; //====== Set Socket to NON-Blocking Mode During Connection so it
ioctlsocket(lhSocket, FIONBIO, (u_long FAR*) &iMode); // Doesn't Hold Up the Show...
// Attempt connect
lConnect = connect(lhSocket,(SOCKADDR *)&lSockAddr,sizeof(SOCKADDR_IN));
iMode = 0; //============== Switch Socket to Blocking Mode to Verify it is Writeable.
ioctlsocket(lhSocket, FIONBIO, (u_long FAR*) &iMode); //====== Socket is in Blocking Mode.
//============ Make or Break Point for Primary Question; IS Spooler Port 515 Active?!?
if(!isSocWriteable(lhSocket)) //==================== IF it Has a Spooler, It IS a Printer!
// if(lConnect != 0)
// On connect failure:
{
// Output result of this scan
sprintf_s(buffer, 64, "%s:%d - Closed\r\n",IPAddress,i);
nTxtLen = GetWindowTextLength(GetDlgItem(m_hWnd,IDT_OUTPUT));
SendMessage(GetDlgItem(m_hWnd,IDT_OUTPUT), EM_SETSEL, nTxtLen, nTxtLen); // move caret to end
SendMessage(GetDlgItem(m_hWnd,IDT_OUTPUT), EM_REPLACESEL, 0, (LPARAM)buffer); // append text
SendMessage(GetDlgItem(m_hWnd,IDT_OUTPUT), EM_SCROLLCARET, 0, 0); // scroll to caret
} else {
// On connect success:
// Output result of this scan
sprintf_s(buffer, 64, "%s:%d - Open\r\n",IPAddress,i);
SendMessage(GetDlgItem(m_hWnd,IDT_OUTPUT), EM_SETSEL, -1, -1); // move caret to end
SendMessage(GetDlgItem(m_hWnd,IDT_OUTPUT), EM_REPLACESEL, 0, (LPARAM)buffer); // append text
SendMessage(GetDlgItem(m_hWnd,IDT_OUTPUT), EM_SCROLLCARET, 0, 0); // scroll to caret
}
shutdown(lhSocket, 0x02); // 0x02 = SD_BOTH
closesocket(lhSocket);
}
// shutdown(lhSocket, 0x02); // 0x02 = SD_BOTH
CloseHandle((void *)lhSocket);
WSACleanup(); //=== Tell WinSock it's Time to Pick-up it's Toys and Go Home.
return TRUE;
}
Note: the top function (isSocWritable()) is entirely mine, the bottom function (has been modified to include the relevant problem child code) is from the LinkSixteen port scanner code which came from StromCode.com's Win32 Turtorial part 8. Which I'm using as a test framework (to avoid getting fired for posting propritery code from the actual application in question
)
The production code outputs to a ListView control & has much more error checking (which is excluded for clarity).