פרויקט: התקן תוכנה עם בקשות מושהות¶
נבנה התקן תוכנה שמקבל מספר ומחזיר את המספר הבא אחרי השהיה. לכאורה אפשר לכתוב את כל החישוב בשורה אחת. העבודה האמיתית מתחילה כשהלקוח מבטל בקשה, סוגר את ה־handle או מסיר את ההתקן בזמן שהמספר עדיין ממתין. המערכת שלנו צריכה להגיע לתוצאה אחת לכל בקשה ולהפסיק כל callback לפני שחרור המצב שעליו הוא עובד.
הפרויקט מחבר את שיעורי הקרנל למערכת אחת שניתן לבדוק מתוך תוכנת C++. הוא אינו דורש חומרה פיזית ואינו מאפשר קריאה או כתיבה של כתובות קרנל שרירותיות. הבקשה נשמרת בתור ידני של KMDF, והטיימר מוציא בכל פעם בקשה אחת. כך אפשר להתמקד בהעברות בעלות אמיתיות בלי להמציא התקן עם רגיסטרים שאין לנו.
סביבת העבודה והגבול של הבדיקה¶
השתמשו במחשב פיתוח עם Visual Studio 2022 ובגרסת WDK 26100.6584 עם SDK תואם. הגדירו בפרויקט KMDF יעד של גרסה 1.33 ובנו עבור x64. סביבת ההרצה היא מכונת Windows 11 וירטואלית מבודדת, עם snapshot, חיבור debugger ומנגנון test signing שהוגדר לצורכי המעבדה. גרסאות אלה הן קיבוע של הקורס, ואינן טענה שהן הגרסאות החדשות ביותר.
הקימו את סביבת היעד לפי הוראות המעבדה וההנחיות הרשמיות לפני שמתקינים את החבילה. הריצו את פקודות ההתקנה ואת Driver Verifier בתוך מכונת היעד בלבד. העתקת הקבצים למחשב הפיתוח אינה הרשאה להתקין עליו את הדרייבר.
הקוד שבפתרון עבר סקירת מקור, אך לא נבנה באמצעות WDK ולא הורץ בקרנל במסגרת כתיבת הקורס. תוצאות של InfVerif, חתימה, טעינה, ביטול והסרת התקן הן חלק מהראיות שאתם צריכים להפיק. בדיקת קומפילציה של הלקוח במצב משתמש אינה מאמתת את הדרייבר.
החוזה שמממשים¶
הגדירו IOCTL אחד בשיטת METHOD_BUFFERED, עם הרשאות קריאה וכתיבה ב־access bits. הקלט והפלט הם זוג ערכי ULONG בגודל שמונה בתים: מספר גרסה ומספר לפעולה. הגרסה הנתמכת היא 1. דחו מספר שערכו MAXULONG כדי למנוע גלישה והחזירו שגיאה לבקשות באורך שונה משמונה בתים.
החזירו פלט מלא ומאותחל בלבד. הצלחה צריכה לדווח בדיוק שמונה בתים, וכל מסלול שגיאה צריך לדווח אפס בתים. הפרוטוקול אינו מכיל מצביעים, מחרוזות באורך לא מוגבל או מבנים שהפריסה שלהם תלויה בגודל מצביע.
החזיקו לכל היותר ארבע בקשות ממתינות בתור הידני. כאשר הוא מלא, דחו קלט חדש לפני העברת הבעלות. הגבול הזה מתייחס לבקשות שהיישום שלנו קיבל לתור, ולא לכל ההקצאות שה־I/O manager או התור הראשי יכולים לבצע בעקבות לקוח שמציף את ההתקן. הגדירו גם מגבלת בקשות בטיסה בצד הלקוח.
השתמשו בטיימר חד־פעמי של מאה מילישניות. הפעילו אותו במעבר מתור ריק לתור שאינו ריק, והפעילו אותו מחדש אם נשארה עבודה אחרי טיפול בבקשה. אל תאפסו את ההשהיה בכל בקשה חדשה, משום שזרם קלט רציף עלול לדחות את הבקשה הראשונה ללא סוף.
הבעלות שעליכם להוכיח¶
הכינו טבלה לכל מעבר: קבלה מהתור הראשי, דחייה, העברה לתור ידני, ביטול כשהבקשה בתור, הוצאה על ידי הטיימר, סיום והסרת התקן. כתבו מי רשאי להשלים את הבקשה בכל שלב ומתי אסור להשתמש יותר ב־WDFREQUEST.
מותר לבקשה להצליח אם הביטול הגיע אחרי שהטיימר כבר לקח אותה והתחיל פעולה קצרה. אסור לפרש את עצם הקריאה ל־CancelIoEx כהוכחה שהבקשה בוטלה. הלקוח שומר את ה־OVERLAPPED ואת ה־bufferים עד הודעת completion סופית, גם אחרי סגירת ה־handle.
קשרו בקשות ל־file object כדי שסגירת לקוח אחד תאפשר לנקות את העבודה שלו. הוכיחו שהלקוח השני אינו מאבד בקשות בעקבות הסגירה. עצרו את הטיימר ורוקנו את התור לפני סיום מעבר הכוח של ההתקן.
חבילת ההגשה¶
הגישו קוד דרייבר, header משותף, קובץ INF, לקוח, הוראות בנייה ותוצאות בדיקה. צרפו טבלת IRQL שמפרידה בין callbacks של קלט ופלט לבין callbacks של PnP וכוח. הוסיפו הסבר מדוע המתנה לסיום הטיימר תחת הנעילה שבה הוא צריך להשתמש יוצרת deadlock.
הגישו עשרה תרחישים לפחות: פעולה תקינה, קלט קצר, פלט קצר, גרסה שגויה, גלישה, קוד פעולה לא מוכר, ביטול, סגירת handle, הסרת התקן עם עבודה ממתינה ופתיחה ללא הרשאה. הוסיפו ניסוי עומס שבודק את הגבול של ארבע בקשות וניסוי restart חוזר תחת Driver Verifier. שמרו לכל ניסיון את גרסת החבילה ואת הפלט, לרבות כישלונות.
הבחינו בין הצלחת תרחיש יחיד לבין הוכחת נכונות בכל תזמון. בצעו לפחות אלף איטרציות של ביטול וסגירה, אך תמכו בתוצאות גם בניתוח בעלות. מספר גבוה של הרצות ללא קריסה אינו מתקן מסלול שמסיים אותה בקשה פעמיים.
תנאי הקבלה¶
המערכת מתקבלת כאשר כל בקשה שהתקבלה מסתיימת פעם אחת, אין כתיבה לפלט שלא אותחל, והסרה אינה משאירה callback שניגש למצב ששוחרר. חובה להסביר כל תלות בגרסת מערכת, לבנות את החבילה בכלי ה־WDK ולהציג תוצאות ממשיות מה־VM.
הניקוד מתחלק לנכונות ב־20%, לבעלות וסנכרון ב־25%, להתאוששות ב־15%, להבנת מנגנוני המערכת ב־15%, למדידה ב־10%, לשחזור ותיעוד ב־10% ולהרחבה עצמאית ב־5%. הציון העובר הוא 80, ובאג של double completion, גישה אחרי שחרור או חשיפת זיכרון לא מאותחל מחייב תיקון גם אם שאר המדדים טובים.