// //The implementation of VirtualAlloc routine,it just calls the appropriate //helper routines according the dwAllocFlags. // static LPVOID kVirtualAlloc(__COMMON_OBJECT* lpThis, LPVOID lpDesiredAddr, DWORD dwSize, DWORD dwAllocFlags, DWORD dwAccessFlags, UCHAR* lpVaName, LPVOID lpReserved) { switch(dwAllocFlags) { case VIRTUAL_AREA_ALLOCATE_IO: //Call DoIoMap only. return DoIoMap(lpThis, lpDesiredAddr, dwSize, dwAllocFlags, dwAccessFlags, lpVaName, lpReserved); case VIRTUAL_AREA_ALLOCATE_RESERVE: return DoReserve(lpThis, lpDesiredAddr, dwSize, dwAllocFlags, dwAccessFlags, lpVaName, lpReserved); case VIRTUAL_AREA_ALLOCATE_ALL: return DoReserveAndCommit(lpThis, lpDesiredAddr, dwSize, dwAllocFlags, dwAccessFlags, lpVaName, lpReserved); case VIRTUAL_AREA_ALLOCATE_COMMIT: return DoCommit(lpThis, lpDesiredAddr, dwSize, dwAllocFlags, dwAccessFlags, lpVaName, lpReserved); case VIRTUAL_AREA_ALLOCATE_IOCOMMIT: return DoIoCommit(lpThis, lpDesiredAddr, dwSize, dwAllocFlags, dwAccessFlags, lpVaName, lpReserved); default: return NULL; } return NULL; }
void AudioTimingControllerKaraoke::AnnounceChanges(int syl) { if (syl < 0) return; if (syl == cur_syl || syl == cur_syl + 1) { AnnounceUpdatedPrimaryRange(); AnnounceUpdatedStyleRanges(); } AnnounceMarkerMoved(); AnnounceLabelChanged(); if (auto_commit) DoCommit(); else { pending_changes = true; commit_id = -1; } }
STDMETHODIMP CCUBRIDRowset::DeleteRows(HCHAPTER hReserved, DBCOUNTITEM cRows, const HROW rghRows[], DBROWSTATUS rgRowStatus[]) { ATLTRACE(atlTraceDBProvider, 2, "CCUBRIDRowset::DeleteRows\n"); ClearError(); if(m_nStatus==1) return RaiseError(E_UNEXPECTED, 1, __uuidof(IRowsetChange), L"This object is in a zombie state"); CHECK_UPDATABILITY(DBPROPVAL_UP_DELETE); if(cRows==0) return S_OK; if(rghRows==NULL && cRows>=1) return RaiseError(E_INVALIDARG, 0, __uuidof(IRowsetChange)); // Determine if we're in immediate or deferred mode bool bDeferred = IsDeferred(this); int hConn = GetSessionPtr()->GetConnection(); UINT uCodepage = GetSessionPtr()->GetCodepage(); BOOL bSuccess = false; BOOL bFailed = false; for(DBCOUNTITEM i=0;i<cRows;i++) { HROW hRow = rghRows[i]; // Attempt to locate the row in our map CCUBRIDRowsetRow *pRow; { bool bFound = m_rgRowHandles.Lookup((ULONG)hRow, pRow); if(!bFound || pRow==NULL) { // invalid handle bFailed = true; if(rgRowStatus) rgRowStatus[i] = DBROWSTATUS_E_INVALID; continue; } } if(pRow->m_status==DBPENDINGSTATUS_DELETED) { // already deleted if(rgRowStatus) rgRowStatus[i] = DBROWSTATUS_E_DELETED; bFailed = true; continue; } ATLASSERT( pRow->m_iRowset==(ULONG)-1 || pRow->m_iRowset<m_rgRowData.GetCount() ); DBROWSTATUS rowStat = DBROWSTATUS_S_OK; // mark the row as deleted if(pRow->m_status==DBPENDINGSTATUS_INVALIDROW) { bFailed = true; // unsigned high bit signified neg. number if(pRow->m_dwRef & 0x80000000) rowStat = DBROWSTATUS_E_INVALID; else rowStat = DBROWSTATUS_E_DELETED; } else if(pRow->m_iRowset==(ULONG)-1 && pRow->m_status!=DBPENDINGSTATUS_NEW) { // 새로 삽입되었고 Storage로 전송됐다. bFailed = true; rowStat = DBROWSTATUS_E_NEWLYINSERTED; } else { bSuccess = true; rowStat = DBROWSTATUS_S_OK; if(pRow->m_status==DBPENDINGSTATUS_NEW) MakeRowInvalid(this, pRow); else pRow->m_status = DBPENDINGSTATUS_DELETED; } if(!bDeferred && pRow->m_status==DBPENDINGSTATUS_DELETED) { // 변화를 지금 적용 // CCUBRIDRowsetRow의 delete는 ReleaseRows에서 이루어진다. HRESULT hr = pRow->WriteData(hConn, uCodepage, GetRequestHandle(), m_strTableName); if(FAILED(hr)) return hr; MakeRowInvalid(this, pRow); } if(rgRowStatus) rgRowStatus[i] = rowStat; } if(!bDeferred) DoCommit(this); // commit if(bFailed) { if(bSuccess) return DB_S_ERRORSOCCURRED; else return RaiseError(DB_E_ERRORSOCCURRED, 0, __uuidof(IRowsetChange)); } else return S_OK; }
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::InsertRow(HCHAPTER hReserved, HACCESSOR hAccessor, void *pData, HROW *phRow) { ATLTRACE(atlTraceDBProvider, 2, "CCUBRIDRowset::InsertRow\n"); if(phRow) *phRow = NULL; if(phRow) CHECK_CANHOLDROWS(__uuidof(IRowsetChange)); ClearError(); if(m_nStatus==1) return RaiseError(E_UNEXPECTED, 1, __uuidof(IRowsetChange), L"This object is in a zombie state"); CHECK_UPDATABILITY(DBPROPVAL_UP_INSERT); // Determine if we're in immediate or deferred mode bool bDeferred = IsDeferred(this); // 바인딩 정보를 구함 ATLBINDINGS *pBinding; { bool bFound = m_rgBindings.Lookup((ULONG)hAccessor, pBinding); if(!bFound || pBinding==NULL) return RaiseError(DB_E_BADACCESSORHANDLE, 0, __uuidof(IRowsetChange)); if(!(pBinding->dwAccessorFlags & DBACCESSOR_ROWDATA)) return RaiseError(DB_E_BADACCESSORTYPE, 0, __uuidof(IRowsetChange)); // row accessor 가 아니다. if(pData==NULL && pBinding->cBindings!=0) return RaiseError(E_INVALIDARG, 0, __uuidof(IRowsetChange)); } CCUBRIDRowsetRow *pRow; CCUBRIDRowsetRow::KeyType key; { // 새 row를 위한 Row class를 생성한다. DBORDINAL cCols; ATLCOLUMNINFO *pColInfo = GetColumnInfo(this, &cCols); ATLTRY(pRow = new CCUBRIDRowsetRow(m_uCodepage, -1, cCols, pColInfo, m_spConvert, m_Columns.m_defaultVal)); if(pRow==NULL) return RaiseError(E_OUTOFMEMORY, 0, __uuidof(IRowsetChange)); // row handle에 추가 key = (CCUBRIDRowsetRow::KeyType)m_rgRowData.GetCount(); if (key == 0) key++; while(m_rgRowHandles.Lookup(key)) key++; m_rgRowHandles.SetAt(key, pRow); // rowset에 데이터가 하나 늘었다. // m_rgRowData.SetCount(m_rgRowData.GetCount()+1); } HRESULT hrRead = pRow->ReadData(pBinding, pData, m_uCodepage); if(FAILED(hrRead)) { // m_rgRowData.SetCount(m_rgRowData.GetCount()-1); m_rgRowHandles.RemoveKey(key); delete pRow; return hrRead; } pRow->m_status = DBPENDINGSTATUS_NEW; if(phRow) { // handle을 반환할 때는 참조 카운트를 하나 증가시킨다. pRow->AddRefRow(); *phRow = (HROW)key; } // m_rgBookmarks.Add(pRow->m_iRowset+1); if(!bDeferred) { // 변화를 지금 적용 int hConn = GetSessionPtr()->GetConnection(); UINT uCodepage = GetSessionPtr()->GetCodepage(); HRESULT hr = pRow->WriteData(hConn, uCodepage, GetRequestHandle(), m_strTableName); if(FAILED(hr)) { pRow->ReleaseRow(); if (phRow != NULL) *phRow = NULL; return hr; } pRow->m_status = 0; // or UNCHANGED? if(pRow->m_dwRef==0) { m_rgRowHandles.RemoveKey(key); delete pRow; } DoCommit(this); // commit //// deferred update 모드였다가 immediate update 모드로 바뀌지는 않으므로 //// 다른 NEW 상태의 row는 없다. 즉 m_iRowset을 변경해야 할 row는 없다. //// 새로 추가된 Row의 OID를 읽어들인다. //pRow->ReadData(GetRequestHandle(), true); } return hrRead; }
STDMETHODIMP CCUBRIDRowset::SetData(HROW hRow, HACCESSOR hAccessor, void *pData) { ATLTRACE(atlTraceDBProvider, 2, "CCUBRIDRowset::SetData\n"); ClearError(); if(m_nStatus==1) return RaiseError(E_UNEXPECTED, 1, __uuidof(IRowsetChange), L"This object is in a zombie state"); // cci_cursor_update를 이용하면 질의를 재실행할 때까지 SetData를 실행할 수 없다. // SQL and cci_execute를 이용하면 가능하다. CHECK_RESTART(__uuidof(IRowsetChange)); CHECK_UPDATABILITY(DBPROPVAL_UP_CHANGE); // Determine if we're in immediate or deferred mode bool bDeferred = IsDeferred(this); // Attempt to locate the row in our map CCUBRIDRowsetRow *pRow; { bool bFound = m_rgRowHandles.Lookup((ULONG)hRow, pRow); if(!bFound || pRow==NULL) return RaiseError(DB_E_BADROWHANDLE, 0, __uuidof(IRowsetChange)); } ATLASSERT( pRow->m_iRowset==(ULONG)-1 || pRow->m_iRowset<m_rgRowData.GetCount() ); // 이미 지워진 row if(pRow->m_status==DBPENDINGSTATUS_DELETED || pRow->m_status==DBPENDINGSTATUS_INVALIDROW) return RaiseError(DB_E_DELETEDROW, 0, __uuidof(IRowsetChange)); // 새로 삽입되었고 Storage로 전송됐다. if(pRow->m_iRowset==(ULONG)-1 && pRow->m_status!=DBPENDINGSTATUS_NEW) return DB_E_NEWLYINSERTED; // 바인딩 정보를 구함 ATLBINDINGS *pBinding; { bool bFound = m_rgBindings.Lookup((ULONG)hAccessor, pBinding); if(!bFound || pBinding==NULL) return RaiseError(DB_E_BADACCESSORHANDLE, 0, __uuidof(IRowsetChange)); if(!(pBinding->dwAccessorFlags & DBACCESSOR_ROWDATA)) return RaiseError(DB_E_BADACCESSORTYPE, 0, __uuidof(IRowsetChange)); // row accessor 가 아니다. if(pData==NULL && pBinding->cBindings!=0) return RaiseError(E_INVALIDARG, 0, __uuidof(IRowsetChange)); } HRESULT hr = pRow->ReadData(pBinding, pData, m_uCodepage); if(FAILED(hr)) return hr; // 새로 삽입된 row는 변경이 있어도 그냥 새로 삽입된 것으로 표시 if(pRow->m_status!=DBPENDINGSTATUS_NEW) pRow->m_status = DBPENDINGSTATUS_CHANGED; if(!bDeferred) { // 변화를 지금 적용 int hConn = GetSessionPtr()->GetConnection(); UINT uCodepage = GetSessionPtr()->GetCodepage(); hr = pRow->WriteData(hConn, uCodepage, GetRequestHandle(), m_strTableName); if (hr == DB_E_INTEGRITYVIOLATION) return RaiseError(DB_E_INTEGRITYVIOLATION, 0, __uuidof(IRowsetChange)); if(FAILED(hr)) return RaiseError(DB_E_ERRORSOCCURRED, 0, __uuidof(IRowsetChange)); pRow->m_status = 0; // or UNCHANGED? DoCommit(this); // commit } return hr; // S_OK or DB_S_ERRORSOCCURRED }
MsgResult CBaseBrushNameDlg::Message(Msg* pMessage) { // A message from the dialog or its gadgets? if (IS_OUR_DIALOG_MSG(pMessage)) { DialogMsg* pMsg = (DialogMsg*) pMessage; switch (pMsg->DlgMsg) { case DIM_CREATE: InitGadgetText(); break; case DIM_TEXT_CHANGED: // Disable the OK/Apply button if there's no document or entered text. EnableGadget(_R(IDOK), !GetStringGadgetValue(_R(IDC_EDITBRUSHNAME), 0).IsEmpty() && Document::GetSelected() != 0); break; case DIM_LFT_BN_CLICKED: // enter messages when the edit box has the focus get cast to this if (pMsg->GadgetID == _R(ID_CC_HELP_BUTTON)) break; case DIM_COMMIT: { // Check name for validity. String_256 strEnter = GetStringGadgetValue(_R(IDC_EDITBRUSHNAME), 0); UINT32 nErrID = IsValid(strEnter); if (nErrID != 0) { // Invalid, reinitialise. InformError(nErrID); if (nErrID == _R(IDS_BRUSHNAME_INVALID)) { String_32 s(strEnter); InitGadgetText(&s, FALSE); } else InitGadgetText(NULL); break; } else { // Entry is valid, try committing it. String_32 FinalString(strEnter); if (DoCommit(strEnter)) { // Don't close, reinitialise (dialog is modeless). InitGadgetText(); pMsg->DlgMsg = DIM_NONE; // stop base class closing it break; } else { // Close(); // End(); - base class will close break; } } } break; case DIM_CANCEL: HandleCancel(); // base class will close break; default: break; } } // Has the document been switched or closed? else if (MESSAGE_IS_A(pMessage, DocChangingMsg)) { DocChangingMsg* pMsg = (DocChangingMsg*) pMessage; if (pMsg->State == DocChangingMsg::SELCHANGED) EnableGadget(_R(IDOK), pMsg->pNewDoc != 0); } // Pass everything on to the base class . . . return DialogOp::Message(pMessage); }
void AudioTimingControllerKaraoke::Commit() { if (!auto_commit && pending_changes) DoCommit(); }
void CMWrongQuestion::Commit() { DoCommit(); }