HRESULT LoadLicenseData(IXMLDOMDocument** ppDocument) { //CEventLog::AddAppLog(_T("LoadLicenseData - Begin"),S_OK,EVENTLOG_ERROR_TYPE); HRESULT hr = E_INVALIDARG; if(!IsBadWritePtr(ppDocument, sizeof(IXMLDOMDocument*))) { hr = CXMLUtil::m_pClassFactory->CreateInstance(NULL, IID_IXMLDOMDocument, (void**)ppDocument); //CEventLog::AddAppLog(_T("LoadLicenseData::m_pClassFactory->CreateInstance"),hr,EVENTLOG_ERROR_TYPE); if(hr == S_OK) { DWORD cbLicenseData; //CEventLog::AddAppLog(_T("LoadLicenseData::GetLicenseDataSize"),hr,EVENTLOG_ERROR_TYPE); hr = GetLicenseDataSize(NULL, PRODUCT_GUID, &cbLicenseData); if(SUCCEEDED(hr)) { //CEventLog::AddAppLog(_T("LoadLicenseData::GetLicenseDataSize - OK"),hr,EVENTLOG_ERROR_TYPE); CHeapPtr<BYTE> pDataBuffer; pDataBuffer.Allocate(cbLicenseData); hr = GetLicenseData(NULL, PRODUCT_GUID, _T("Mediachase_IbnServer_4.7"), pDataBuffer, &cbLicenseData); //CEventLog::AddAppLog(_T("LoadLicenseData::GetLicenseData - OK"),hr,EVENTLOG_ERROR_TYPE); if(SUCCEEDED(hr)) hr = CXMLUtil::MEM2XML(*ppDocument, pDataBuffer, cbLicenseData); } else hr = E_FAIL; } } //CEventLog::AddAppLog(_T("LoadLicenseData - End"),hr,EVENTLOG_ERROR_TYPE); return hr; }
BOOL CEnumerateSerial::EnumeratePorts() { int SPDRPlist[] = { SPDRP_DEVICEDESC, SPDRP_FRIENDLYNAME, SPDRP_MFG, SPDRP_LOCATION_INFORMATION, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, -1}; // Clear anything from previous enumerate... ResetPortList(); // Dynamically get pointers to device installation library (setupapi.dll) // in case it isn't installed... // SetupDiOpenDevRegKey // SetupDiEnumDeviceInfo // SetupDiDestroyDeviceInfoList // SetupDiGetClassDevs // SetupDiClassGuidsFromName // SetupDiGetDeviceRegistryProperty CLoadLib setupAPI(_T("SETUPAPI.DLL")); if (setupAPI == NULL) return FALSE; #define SETUPPROC(x,y) x* lpfn##x = reinterpret_cast<x*>(GetProcAddress(setupAPI,y)) SETUPPROC(SETUPDIOPENDEVREGKEY,"SetupDiOpenDevRegKey"); SETUPPROC(SETUPDIENUMDEVICEINFO, "SetupDiEnumDeviceInfo"); SETUPPROC(SETUPDIDESTROYDEVICEINFOLIST, "SetupDiDestroyDeviceInfoList"); #if defined _UNICODE SETUPPROC(SETUPDIGETCLASSDEVS, "SetupDiGetClassDevsW"); SETUPPROC(SETUPDICLASSGUIDSFROMNAME, "SetupDiClassGuidsFromNameW"); SETUPPROC(SETUPDIGETDEVICEREGISTRYPROPERTY, "SetupDiGetDeviceRegistryPropertyW"); #else SETUPPROC(SETUPDIGETCLASSDEVS, "SetupDiGetClassDevsA"); SETUPPROC(SETUPDICLASSGUIDSFROMNAME, "SetupDiClassGuidsFromNameA"); SETUPPROC(SETUPDIGETDEVICEREGISTRYPROPERTY, "SetupDiGetDeviceRegistryPropertyA"); #endif if ((lpfnSETUPDIOPENDEVREGKEY == NULL) || (lpfnSETUPDIENUMDEVICEINFO == NULL) || (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY == NULL) || (lpfnSETUPDIGETCLASSDEVS == NULL) || (lpfnSETUPDICLASSGUIDSFROMNAME == NULL) || (lpfnSETUPDIDESTROYDEVICEINFOLIST == NULL)) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } // First need to convert the name "Ports" to a GUID using SetupDiClassGuidsFromName... DWORD dwGuids = 0; lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), NULL, 0, &dwGuids); if (dwGuids == 0) return FALSE; // Allocate the needed memory... CHeapPtr<GUID> GuidArray; GUID *pGuids = (GUID*)GuidArray.Allocate(sizeof(GUID) * dwGuids); if (pGuids==NULL) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } // Call the function again... if (!lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), pGuids, dwGuids, &dwGuids)) return FALSE; // Now create a "device information set" which is required to enumerate all the ports... HDEVINFO hDevInfoSet = lpfnSETUPDIGETCLASSDEVS(pGuids, NULL, NULL, DIGCF_PRESENT); if (hDevInfoSet == INVALID_HANDLE_VALUE) return FALSE; // Finally do the enumeration... int nIndex = 0; SP_DEVINFO_DATA devInfo; CHeapPtr<TCHAR> tempstr(256); CSerialPortInfo *portinfo = NULL; // Enumerate the current device... devInfo.cbSize = sizeof(SP_DEVINFO_DATA); while (lpfnSETUPDIENUMDEVICEINFO(hDevInfoSet, nIndex, &devInfo)) { portinfo = NULL; // Get the registry key which stores the ports settings... HKEY hDeviceKey = lpfnSETUPDIOPENDEVREGKEY(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); if (hDeviceKey) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; // Read name of port. If formatted as "COMxx" then allocate a port slot... if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, reinterpret_cast<LPBYTE>((TCHAR*)tempstr), &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ)) if (_tcslen(tempstr) > 3) if ((_tcsnicmp(tempstr, _T("COM"), 3) == 0) && IsNumber(&(tempstr[3]))) portinfo = AddPort(_ttoi(&(tempstr[3]))); // Close the key now that we are finished with it... RegCloseKey(hDeviceKey); } // If a serial port, then try getting additional useful descriptive info... if (portinfo) { for (int i=0; SPDRPlist[i]>=0; i++) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; if (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY(hDevInfoSet, &devInfo, SPDRPlist[i], &dwType, reinterpret_cast<PBYTE>((TCHAR*)tempstr), dwSize, &dwSize) && (dwType == REG_SZ)) switch (SPDRPlist[i]) { case SPDRP_MFG : portinfo->SetManufacturer(tempstr); break; case SPDRP_DEVICEDESC : portinfo->SetDeviceDesc(tempstr); break; case SPDRP_FRIENDLYNAME : portinfo->SetFriendlyName(tempstr); break; case SPDRP_LOCATION_INFORMATION : portinfo->SetLocationInfo(tempstr); break; case SPDRP_PHYSICAL_DEVICE_OBJECT_NAME : portinfo->SetPhysLocation(tempstr); break; } } // Get COM port properties... HANDLE hPort = ::CreateFile(portinfo->GetPortDeviceName(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (hPort != INVALID_HANDLE_VALUE) { COMMPROP cp; GetCommProperties(hPort, &cp); portinfo->SetCommProp(cp); TRACE ("Port %d: CommProp: maxbaud=%08x settablebaud=%08x\n",portinfo->GetPortNum(),cp.dwMaxBaud,cp.dwSettableBaud); CloseHandle(hPort); } } ++nIndex; } // Free up the "device information set" now that we are finished with it lpfnSETUPDIDESTROYDEVICEINFOLIST(hDevInfoSet); // Return the success indicator return TRUE; }
STDMETHODIMP CCUBRIDRowset::Update(HCHAPTER hReserved, DBCOUNTITEM cRows, const HROW rghRows[], DBCOUNTITEM *pcRows, HROW **prgRows, DBROWSTATUS **prgRowStatus) { ATLTRACE(atlTraceDBProvider, 2, "CCUBRIDRowset::Update\n"); ClearError(); if(m_nStatus==1) return RaiseError(E_UNEXPECTED, 1, __uuidof(IRowsetUpdate), L"This object is in a zombie state"); CHECK_RESTART(__uuidof(IRowsetUpdate)); DBCOUNTITEM ulRows = 0; // update할 row 수 bool bNotIgnore = true; // prgRows, prgRowStatus를 무시할지 여부를 나타냄 // the following lines are used to fix the two _alloca calls below. Those calls are risky // because we may be allocating huge amounts of data. So instead I'll allocate that data on heap. // But if you use _alloca you don't have to worry about cleaning this memory. So we will use these // temporary variables to allocate memory on heap. As soon as we exit the function, the memory will // be cleaned up, just as if we were using alloca. So now, instead of calling alloca, I'll alloc // memory on heap using the two smnart pointers below, and then assing it to the actual pointers. CHeapPtr<HROW> spTempRows; CHeapPtr<DBROWSTATUS> spTempRowStatus; if(cRows || pcRows) { if(prgRows) *prgRows = NULL; if(prgRowStatus) *prgRowStatus = NULL; } else { bNotIgnore = false; // Don't do status or row arrays } // Check to see how many changes we'll undo if(pcRows) { *pcRows = NULL; if(prgRows==NULL) return E_INVALIDARG; } if(cRows) { if(rghRows==NULL) return E_INVALIDARG; ulRows = cRows; } else ulRows = (DBCOUNTITEM)m_rgRowHandles.GetCount(); int hConn = GetSessionPtr()->GetConnection(); UINT uCodepage = GetSessionPtr()->GetCodepage(); // NULL out pointers { if(prgRows && ulRows && bNotIgnore) { // Make a temporary buffer as we may not fill up everything // in the case where cRows == 0 if(cRows) *prgRows = (HROW*)CoTaskMemAlloc(ulRows * sizeof(HROW)); else { spTempRows.Allocate(ulRows); *prgRows = spTempRows; } if (*prgRows==NULL) return E_OUTOFMEMORY; } if(prgRowStatus && ulRows && bNotIgnore) { if(cRows) *prgRowStatus = (DBROWSTATUS*)CoTaskMemAlloc(ulRows * sizeof(DBROWSTATUS)); else { spTempRowStatus.Allocate(ulRows); *prgRowStatus = spTempRowStatus; } if(*prgRowStatus==NULL) { if(cRows) CoTaskMemFree(*prgRows); *prgRows = NULL; return E_OUTOFMEMORY; } } } bool bSucceeded = false; bool bFailed = false; ULONG ulCount = 0; // update된 row 수 POSITION pos = m_rgRowHandles.GetStartPosition(); for (ULONG ulRow = 0; ulRow < ulRows; ulRow++) { ULONG ulCurrentRow = ulCount; bool bDupRow = false; // 중복된 row ULONG ulAlreadyProcessed = 0; // 중복된 row의 handle의 위치 HROW hRowUpdate = NULL; // 현재 update할 row의 handle { if(cRows) { // row handle이 주어졌음 hRowUpdate = rghRows[ulRow]; for (ULONG ulCheckDup = 0; ulCheckDup < ulRow; ulCheckDup++) { if (hRowUpdate==rghRows[ulCheckDup] || IsSameRow(hRowUpdate, rghRows[ulCheckDup]) == S_OK) { ulAlreadyProcessed = ulCheckDup; bDupRow = true; break; } } } else { // 모든 row에 대해 update //ATLASSERT(ulRow < (ULONG)m_rgRowHandles.GetCount()); // delete된 row가 있으면 성립하지 않는다. ATLASSERT( pos != NULL ); MapClass::CPair* pPair = m_rgRowHandles.GetNext(pos); ATLASSERT( pPair != NULL ); hRowUpdate = pPair->m_key; } } if(prgRows && bNotIgnore) (*prgRows)[ulCurrentRow] = hRowUpdate; if(bDupRow) { // We've already set the row before, just copy status and // continue processing if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = (*prgRowStatus)[ulAlreadyProcessed]; ulCount++; continue; } // Fetch the RowClass and determine if it is valid CCUBRIDRowsetRow *pRow; { bool bFound = m_rgRowHandles.Lookup((ULONG)hRowUpdate, pRow); if (!bFound || pRow == NULL) { if (prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_E_INVALID; bFailed = true; ulCount++; continue; } } // If cRows is zero we'll go through all rows fetched. We // shouldn't increment the attempted count for rows that are // not changed if (cRows != 0 || (pRow != NULL && pRow->m_status != 0 && pRow->m_status != DBPENDINGSTATUS_UNCHANGED && pRow->m_status != DBPENDINGSTATUS_INVALIDROW)) ulCount++; else continue; if(cRows==0) pRow->AddRefRow(); switch (pRow->m_status) { case DBPENDINGSTATUS_INVALIDROW: // Row is bad or deleted { if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_E_DELETED; bFailed = true; } break; case DBPENDINGSTATUS_UNCHANGED: case 0: { // If the row's status is not changed, then just put S_OK // and continue. The spec says we should not transmit the // request to the data source (as nothing would change). if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_S_OK; bSucceeded = true; } break; default: { DBORDINAL cCols; ATLCOLUMNINFO *pColInfo = GetColumnInfo(this, &cCols); HRESULT hr = pRow->WriteData(hConn, uCodepage, GetRequestHandle(), m_strTableName); if(FAILED(hr)) { DBROWSTATUS stat = DBROWSTATUS_E_FAIL; if(hr==DB_E_INTEGRITYVIOLATION) stat = DBROWSTATUS_E_INTEGRITYVIOLATION; if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = stat; bFailed = true; } else { //// m_iRowset을 적당히 조정한다. //if(pRow->m_status==DBPENDINGSTATUS_NEW) //{ // // NEW인 row는 항상 rowset의 뒤에 몰려있다. // // 그 row 중 가장 작은 m_iRowset이 update 된 row의 m_iRowset이 되면 된다. // CCUBRIDRowsetRow::KeyType key = pRow->m_iRowset; // POSITION pos = m_rgRowHandles.GetStartPosition(); // while(pos) // { // CCUBRIDRowset::MapClass::CPair *pPair = m_rgRowHandles.GetNext(pos); // ATLASSERT(pPair); // CCUBRIDRowsetRow *pCheckRow = pPair->m_value; // if( pCheckRow && pCheckRow->m_iRowset < key ) // { // if(pCheckRow->m_iRowset<pRow->m_iRowset) // pRow->m_iRowset = pCheckRow->m_iRowset; // pCheckRow->m_iRowset++; // } // } // // TODO: 북마크 업데이트가 필요한데 어떻게 해야 할지 모르겠다. // // 새로 추가된 Row의 OID를 읽어들인다. // pRow->ReadData(GetRequestHandle(), true); //} if(pRow->m_status==DBPENDINGSTATUS_DELETED) MakeRowInvalid(this, pRow); else pRow->m_status = DBPENDINGSTATUS_UNCHANGED; if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_S_OK; bSucceeded = true; // Check if we need to release the row because it's ref was 0 // See the IRowset::ReleaseRows section in the spec for more // information if (pRow->m_dwRef == 0) { pRow->AddRefRow(); // Artifically bump this to remove it if( FAILED( RefRows(1, &hRowUpdate, NULL, NULL, false) ) ) return E_FAIL; } } } break; } } // Set the output for rows undone. if(pcRows) *pcRows = ulCount; if(ulCount==0) { if(prgRows) { CoTaskMemFree(*prgRows); *prgRows = NULL; } if(prgRowStatus) { CoTaskMemFree(*prgRowStatus); *prgRowStatus = NULL; } } else if(cRows==0) { // In the case where cRows == 0, we need to allocate the final // array of data. if(prgRows && bNotIgnore) { HROW *prgRowsTemp = (HROW *)CoTaskMemAlloc(ulCount*sizeof(HROW)); if(prgRowsTemp==NULL) return E_OUTOFMEMORY; memcpy(prgRowsTemp, *prgRows, ulCount*sizeof(HROW)); *prgRows = prgRowsTemp; } if(prgRowStatus && bNotIgnore) { DBROWSTATUS *prgRowStatusTemp = (DBROWSTATUS *)CoTaskMemAlloc(ulCount*sizeof(DBROWSTATUS)); if(prgRowStatusTemp==NULL) { CoTaskMemFree(*prgRows); *prgRows = NULL; return E_OUTOFMEMORY; } memcpy(prgRowStatusTemp, *prgRowStatus, ulCount*sizeof(DBROWSTATUS)); *prgRowStatus = prgRowStatusTemp; } } DoCommit(this); // commit // Send the return value if(!bFailed) return S_OK; else { return bSucceeded ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED; } }
STDMETHODIMP CCUBRIDRowset::Undo(HCHAPTER hReserved, DBCOUNTITEM cRows, const HROW rghRows[], DBCOUNTITEM *pcRowsUndone, HROW **prgRowsUndone, DBROWSTATUS **prgRowStatus) { ATLTRACE(atlTraceDBProvider, 2, "CCUBRIDRowset::Undo\n"); ClearError(); if(m_nStatus==1) return RaiseError(E_UNEXPECTED, 1, __uuidof(IRowsetUpdate), L"This object is in a zombie state"); CHECK_RESTART(__uuidof(IRowsetUpdate)); DBCOUNTITEM ulRows = 0; // undo할 row 수 bool bNotIgnore = true; // prgRowsUndone, prgRowStatus를 무시할지 여부를 나타냄 // the following lines are used to fix the two _alloca calls below. Those calls are risky // because we may be allocating huge amounts of data. So instead I'll allocate that data on heap. // But if you use _alloca you don't have to worry about cleaning this memory. So we will use these // temporary variables to allocate memory on heap. As soon as we exit the function, the memory will // be cleaned up, just as if we were using alloca. So now, instead of calling alloca, I'll alloc // memory on heap using the two smnart pointers below, and then assing it to the actual pointers. CHeapPtr<HROW> spTempRowsUndone; CHeapPtr<DBROWSTATUS> spTempRowStatus; if(cRows || pcRowsUndone) { if(prgRowsUndone) *prgRowsUndone = NULL; if(prgRowStatus) *prgRowStatus = NULL; } else { bNotIgnore = false; // Don't do status or row arrays } // Check to see how many changes we'll undo if(pcRowsUndone) { *pcRowsUndone = NULL; if(prgRowsUndone==NULL) return E_INVALIDARG; } if(cRows) { if(rghRows==NULL) return E_INVALIDARG; ulRows = cRows; } else ulRows = (DBCOUNTITEM)m_rgRowHandles.GetCount(); // NULL out pointers { if(prgRowsUndone && ulRows && bNotIgnore) { // Make a temporary buffer as we may not fill up everything // in the case where cRows == 0 if(cRows) *prgRowsUndone = (HROW*)CoTaskMemAlloc(ulRows * sizeof(HROW)); else { spTempRowsUndone.Allocate(ulRows); *prgRowsUndone = spTempRowsUndone; } if (*prgRowsUndone==NULL) return E_OUTOFMEMORY; } if(prgRowStatus && ulRows && bNotIgnore) { if(cRows) *prgRowStatus = (DBROWSTATUS*)CoTaskMemAlloc(ulRows * sizeof(DBROWSTATUS)); else { spTempRowStatus.Allocate(ulRows); *prgRowStatus = spTempRowStatus; } if(*prgRowStatus==NULL) { if(cRows) CoTaskMemFree(*prgRowsUndone); *prgRowsUndone = NULL; return E_OUTOFMEMORY; } } } bool bSucceeded = false; bool bFailed = false; ULONG ulUndone = 0; // undo된 row 수 POSITION pos = m_rgRowHandles.GetStartPosition(); for (ULONG ulUndoRow = 0; ulUndoRow < ulRows; ulUndoRow++) { ULONG ulCurrentRow = ulUndone; HROW hRowUndo = NULL; // 현재 undo할 row의 handle { if(cRows) { // row handle이 주어졌음 hRowUndo = rghRows[ulUndoRow]; } else { // 모든 row에 대해 undo // ATLASSERT(ulUndoRow < (ULONG)m_rgRowHandles.GetCount()); // delete된 row가 있으면 성립하지 않는다. ATLASSERT( pos != NULL ); MapClass::CPair* pPair = m_rgRowHandles.GetNext(pos); ATLASSERT( pPair != NULL ); hRowUndo = pPair->m_key; } } if(prgRowsUndone && bNotIgnore) (*prgRowsUndone)[ulCurrentRow] = hRowUndo; // Fetch the RowClass and determine if it is valid CCUBRIDRowsetRow *pRow; { bool bFound = m_rgRowHandles.Lookup((ULONG)hRowUndo, pRow); if (!bFound || pRow == NULL) { if (prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_E_INVALID; bFailed = true; ulUndone++; continue; } } // If cRows is zero we'll go through all rows fetched. We shouldn't // increment the count for rows that haven't been modified. if (cRows != 0 || (pRow != NULL && pRow->m_status != 0 && pRow->m_status != DBPENDINGSTATUS_UNCHANGED && pRow->m_status != DBPENDINGSTATUS_INVALIDROW)) ulUndone++; else continue; if(cRows==0) pRow->AddRefRow(); switch (pRow->m_status) { case DBPENDINGSTATUS_INVALIDROW: // 메모리와 storage 모두 존재하지 않는 row { // provider templates에서는 DELETED인데 // INVALID가 더 맞지 않을까 싶기도 한다. if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_E_DELETED; bFailed = true; } break; case DBPENDINGSTATUS_NEW: // 메모리 상에만 존재하는 row { // If the row is newly inserted, go ahead and mark its // row as INVALID (according to the specification). if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_S_OK; MakeRowInvalid(this, pRow); bSucceeded = true; } break; case DBPENDINGSTATUS_CHANGED: case DBPENDINGSTATUS_DELETED: // storage의 데이터를 가져와야 하는 경우 // delete 된 경우 메모리에 데이터가 있지만, CHANGED->DELETED 인 경우도 있을 수 있다. { // read data back pRow->ReadData(GetRequestHandle()); pRow->m_status = DBPENDINGSTATUS_UNCHANGED; if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_S_OK; bSucceeded = true; } break; default: // 0, DBPENDINGSTATUS_UNCHANGED, // storage의 데이터를 가져올 필요가 없는 경우 { pRow->m_status = DBPENDINGSTATUS_UNCHANGED; if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_S_OK; bSucceeded = true; } break; } // Check if we need to release the row because it's ref was 0 // See the IRowset::ReleaseRows section in the spec for more // information if (pRow->m_dwRef == 0) { pRow->AddRefRow(); // Artifically bump this to remove it if( FAILED( RefRows(1, &hRowUndo, NULL, NULL, false) ) ) return E_FAIL; } } // Set the output for rows undone. if(pcRowsUndone) *pcRowsUndone = ulUndone; if(ulUndone==0) { if(prgRowsUndone) { CoTaskMemFree(*prgRowsUndone); *prgRowsUndone = NULL; } if(prgRowStatus) { CoTaskMemFree(*prgRowStatus); *prgRowStatus = NULL; } } else if(cRows==0) { // In the case where cRows == 0, we need to allocate the final // array of data. if(prgRowsUndone && bNotIgnore) { HROW *prgRowsTemp = (HROW *)CoTaskMemAlloc(ulUndone*sizeof(HROW)); if(prgRowsTemp==NULL) return E_OUTOFMEMORY; memcpy(prgRowsTemp, *prgRowsUndone, ulUndone*sizeof(HROW)); *prgRowsUndone = prgRowsTemp; } if(prgRowStatus && bNotIgnore) { DBROWSTATUS *prgRowStatusTemp = (DBROWSTATUS *)CoTaskMemAlloc(ulUndone*sizeof(DBROWSTATUS)); if(prgRowStatusTemp==NULL) { CoTaskMemFree(*prgRowsUndone); *prgRowsUndone = NULL; return E_OUTOFMEMORY; } memcpy(prgRowStatusTemp, *prgRowStatus, ulUndone*sizeof(DBROWSTATUS)); *prgRowStatus = prgRowStatusTemp; } } // Send the return value if(!bFailed) return S_OK; else { return bSucceeded ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED; } }
BOOL CEnumerateSerial::EnumeratePorts() { int SPDRPlist[] = { SPDRP_HARDWAREID, SPDRP_DEVICEDESC, SPDRP_FRIENDLYNAME, SPDRP_MFG, SPDRP_LOCATION_INFORMATION, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, -1}; // Clear anything from previous enumerate... ResetPortList(); // First need to convert the name "Ports" to a GUID using SetupDiClassGuidsFromName... DWORD dwGuids = 0; SetupDiClassGuidsFromName(_T("Ports"), NULL, 0, &dwGuids); if (dwGuids == 0) return FALSE; // Allocate the needed memory... CHeapPtr<GUID> GuidArray; GUID *pGuids = (GUID*)GuidArray.Allocate(sizeof(GUID) * dwGuids); if (pGuids==NULL) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } // Call the function again... if (!SetupDiClassGuidsFromName(_T("Ports"), pGuids, dwGuids, &dwGuids)) return FALSE; // Now create a "device information set" which is required to enumerate all the ports... HDEVINFO hDevInfoSet = SetupDiGetClassDevs(pGuids, NULL, NULL, DIGCF_PRESENT); if (hDevInfoSet == INVALID_HANDLE_VALUE) return FALSE; // Finally do the enumeration... int nIndex = 0; SP_DEVINFO_DATA devInfo; CHeapPtr<TCHAR> tempstr(1000); CSerialPortInfo *portinfo = NULL; // Enumerate the current device... devInfo.cbSize = sizeof(SP_DEVINFO_DATA); while (SetupDiEnumDeviceInfo(hDevInfoSet, nIndex, &devInfo)) { portinfo = NULL; // Get the registry key which stores the ports settings... HKEY hDeviceKey = SetupDiOpenDevRegKey(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); if (hDeviceKey) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; // Read name of port. If formatted as "COMxx" then allocate a port slot... if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, reinterpret_cast<LPBYTE>((TCHAR*)tempstr), &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ)) if (_tcslen(tempstr) > 3) if ((_tcsnicmp(tempstr, _T("COM"), 3) == 0) && IsNumber(&(tempstr[3]))) portinfo = AddPort(_ttoi(&(tempstr[3]))); // Close the key now that we are finished with it... RegCloseKey(hDeviceKey); } // If a serial port, then try getting additional useful descriptive info... if (portinfo) { for (int i=0; SPDRPlist[i]>=0; i++) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRPlist[i], &dwType, reinterpret_cast<PBYTE>((TCHAR*)tempstr), dwSize, &dwSize) && ((dwType == REG_SZ) || (dwType == REG_MULTI_SZ))) switch (SPDRPlist[i]) { case SPDRP_MFG : portinfo->SetManufacturer(tempstr); break; case SPDRP_HARDWAREID : portinfo->SetHardwareID(tempstr); break; case SPDRP_DEVICEDESC : portinfo->SetDeviceDesc(tempstr); break; case SPDRP_FRIENDLYNAME : portinfo->SetFriendlyName(tempstr); break; case SPDRP_LOCATION_INFORMATION : portinfo->SetLocationInfo(tempstr); break; case SPDRP_PHYSICAL_DEVICE_OBJECT_NAME : portinfo->SetPhysLocation(tempstr); break; } } // Get COM port properties... HANDLE hPort = ::CreateFile(portinfo->GetPortDeviceName(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (hPort != INVALID_HANDLE_VALUE) { COMMPROP cp; GetCommProperties(hPort, &cp); portinfo->SetCommProp(cp); TRACE ("Port %d: CommProp: maxbaud=%08x settablebaud=%08x\n",portinfo->GetPortNum(),cp.dwMaxBaud,cp.dwSettableBaud); CloseHandle(hPort); } } ++nIndex; } // Free up the "device information set" now that we are finished with it SetupDiDestroyDeviceInfoList(hDevInfoSet); // Return the success indicator return TRUE; }
HRESULT PasswordUtil_Check(LPCWSTR password, LPCWSTR salt, LPCWSTR passwordHash, BOOL* pResult) { if(IsBadStringPtrW(password,512)) return E_INVALIDARG; if(IsBadStringPtrW(salt,512)) return E_INVALIDARG; if(IsBadStringPtrW(passwordHash,512)) return E_INVALIDARG; if(IsBadWritePtr(pResult,sizeof(BOOL*))) return E_INVALIDARG; *pResult = FALSE; HRESULT hr = S_OK; HCRYPTPROV hProv = NULL; HCRYPTHASH hHash = NULL; WCHAR saltAndPwd[1024] = L""; wcsncat_s(saltAndPwd, 1024, password, 512); wcsncat_s(saltAndPwd, 1024, L"$",1); wcsncat_s(saltAndPwd, 1024, salt, 511); DWORD dwFlags = CRYPT_SILENT|CRYPT_MACHINE_KEYSET; TCHAR szContainer[50] = _T("{BDECD56B-6D48-4add-9AEE-265D537408DF}"); CString auditMessage; BOOL bCreated = FALSE; if(!CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, dwFlags)) { hr = HRESULT_FROM_WIN32(GetLastError()); if(hr==0x80090016L) // Key Not Found { bCreated = TRUE; if(!CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET|dwFlags)) { hr = HRESULT_FROM_WIN32(GetLastError()); if(hr == 0x8009000FL) // Key Exists { if(CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET|dwFlags)) { hr = S_OK; if(!CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET|dwFlags)) { hr = HRESULT_FROM_WIN32(GetLastError()); } else { hr = S_OK; } } else { hr = HRESULT_FROM_WIN32(GetLastError()); } } else { hr = S_OK; } } else { hr = S_OK; } } } if(SUCCEEDED(hr)) { if(bCreated) { // Set DACL for this container to allow full control for everyone and for local system. PSECURITY_DESCRIPTOR pSd = NULL; LPBYTE pbDacl = NULL; HRESULT hr2 = CreateSecurityDescriptor(&pSd, &pbDacl); if(SUCCEEDED(hr2)) { CryptSetProvParam(hProv, PP_KEYSET_SEC_DESCR, reinterpret_cast<LPBYTE>(pSd), DACL_SECURITY_INFORMATION); delete pSd; delete[] pbDacl; } } if(CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { //auditMessage.Format(_T("Step 2-2. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); if(CryptHashData(hHash, (BYTE*)saltAndPwd, (DWORD)(wcslen(saltAndPwd))*2, 0)) { //auditMessage.Format(_T("Step 2-3. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); BYTE szData[50] = {0}; DWORD dwDataLen = 50; if(CryptGetHashParam(hHash, HP_HASHVAL, szData, &dwDataLen, 0)) { /*auditMessage.Format(_T("Step 2-4. Error Code: 0x%X."), hr); CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE);*/ CW2A ansiPasswordHash(passwordHash); int passwordHashLen = static_cast<int>(strlen(ansiPasswordHash)); int nDestLen = Base64DecodeGetRequiredLength(passwordHashLen); CHeapPtr<BYTE> dataBuffer; if(dataBuffer.AllocateBytes(nDestLen)) { //auditMessage.Format(_T("Step 2-5. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); if(Base64Decode(ansiPasswordHash, passwordHashLen, dataBuffer, &nDestLen)) { size_t testHashLength = static_cast<size_t>(dwDataLen); size_t validHashLength = static_cast<size_t>(nDestLen); *pResult = (testHashLength == validHashLength && (memcmp(szData, dataBuffer, testHashLength) == 0)); } } else hr = E_OUTOFMEMORY; } else hr = HRESULT_FROM_WIN32(GetLastError()); } else hr = HRESULT_FROM_WIN32(GetLastError()); CryptDestroyHash(hHash); } else hr = HRESULT_FROM_WIN32(GetLastError()); CryptReleaseContext(hProv, 0); } //else // hr = HRESULT_FROM_WIN32(GetLastError()); //auditMessage.Format(_T("Step Final. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); return hr; }