לדלג לתוכן

פתרון שמות פתיחה וזהות קובץ

קישור קשיח נוסף באותה מערכת קבצים מציג שם נוסף לאותו קובץ. לכן צפוי לקבל אותה זהות בהקשר ה־volume, אף ששמות הנתיב שונים. לאחר מחיקה ויצירה מחדש אין להניח שהזהות נשמרת. הבדיקה צריכה לשמור את התוצאות האמיתיות ואת סוג מערכת הקבצים.

מעטפת RAII יכולה להשתמש בחוזה מוכר של CreateFileW:

class FileHandle {
    HANDLE value_ = INVALID_HANDLE_VALUE;
public:
    explicit FileHandle(HANDLE value) noexcept : value_(value) {}
    ~FileHandle() {
        if (value_ != INVALID_HANDLE_VALUE) CloseHandle(value_);
    }
    FileHandle(const FileHandle&) = delete;
    FileHandle& operator=(const FileHandle&) = delete;
    HANDLE get() const noexcept { return value_; }
};

הקטע מצטרף לקוד ההרצאה אחרי הכותרות. לאחר יצירת FileHandle מחליפים את השימושים ב־file ב־file.get ומסירים את קריאות CloseHandle הידניות. כך חריגה מתוך resize אינה מדליפה את ה־handle. מסלול הדיווח יכול לתפוס std::exception בגבול main בלי להעמיד פנים שהנתיב התקבל.

בדיקת שיתוף

אם התוכנית הראשונה פותחת לקריאה עם share mode אפס, היא אינה מסכימה לפתיחות נוספות בגישות המתנגשות. התוכנית השנייה יכולה להיכשל למרות שיש לה הרשאה לקרוא את הקובץ. כאשר הראשונה מאפשרת FILE_SHARE_READ והשנייה מבקשת קריאה עם שיתוף מתאים, שתיהן יכולות להצליח.

ההסבר צריך להפריד בין access denied לבין sharing violation, ולשמור את GetLastError מיד אחרי הכשל. קריאה לפונקציה אחרת לפני שמירת הקוד עלולה לשנות את המידע שרצינו לאבחן.

מרוץ שם

נניח שהקוד בודק שרכיב תיקייה מסוים אינו קישור, ואז thread אחר מחליף את הרכיב לפני CreateFileW. הפתיחה משתמשת במצב החדש. נרמול המחרוזת לפני הפתיחה אינו מקבע את מבנה מערכת הקבצים.

בדיקה מתוך handle מתייחסת לאובייקט שנפתח בפועל, למשל זהותו ומאפייניו. אבל גם השוואת נתיב סופי לקידומת אינה מדיניות שלמה כאשר קיימים קישורים קשיחים, רגישות משתנה לאותיות והרשאות שונות. צריך להגדיר מה מותר: גישה לאובייקט בעל זהות מסוימת, גישה תחת תיקייה מוגנת או פעולה בשם שהמשתמש סיפק. ההגדרה קודמת לבחירת פונקציית העזר.

אם FileIdInfo אינו נתמך, הדוח אומר שזהות זו לא התקבלה. אפשר לבחור מנגנון חלופי שמתאים לספק, אך אין להחזיר מזהה אפס ולסמן שהבדיקה הצליחה.